From 326269b02691d7d6adf6b3794f0aac8d3a119d99 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 13 Dec 2014 13:13:01 -0800 Subject: [PATCH 0001/1122] Change Makefile so it's easier Now you just type `make book` or `make serve`, without having to add GITBOOK=`pwd`/node_modules/.bin/gitbook. Also, now npm installs it automatically on first run. --- Makefile | 9 ++++++--- README.md | 7 +++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 501726ba69..98d70e476f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -GITBOOK = gitbook +GITBOOK = ../node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -A experimental @@ -29,7 +29,7 @@ all: $(RUSTC) src/update.rs --out-dir bin bin/update -book: +book: node_modules/gitbook cd stage && $(GITBOOK) build ./fix-edit-button.sh ./add-relinks.sh @@ -41,5 +41,8 @@ test: $(foreach src,$(srcs),$(RUSTC_NT) $(src) || exit;) ./check-line-length.sh -serve: +serve: node_modules/gitbook cd stage && $(GITBOOK) serve + +node_modules/gitbook: + npm install gitbook@0.7.1 diff --git a/README.md b/README.md index e616dc7caa..f81844762f 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,12 @@ See [CONTRIBUTING.md][how-to-contribute]. ## How to generate the static site ``` -npm install gitbook@0.7.1 make all -make book GITBOOK=`pwd`/node_modules/.bin/gitbook -make test GITBOOK=`pwd`/node_modules/.bin/gitbook +make book +make test ``` -View the results with ```make serve GITBOOK=`pwd`/node_modules/.bin/gitbook```. +View the results with `make serve`. Note: on Ubuntu `node` may be called `nodejs`. I had to edit `.bin/gitbook` accordingly. From 65d2c5c33b949bfef65660a08a6600a6eaecb46d Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 13 Dec 2014 15:01:12 -0800 Subject: [PATCH 0002/1122] Why did we cd into stage in the first place This works perfectly, as far as I can tell. --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 98d70e476f..0bd3663950 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -GITBOOK = ../node_modules/.bin/gitbook +GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -A experimental @@ -30,7 +30,7 @@ all: bin/update book: node_modules/gitbook - cd stage && $(GITBOOK) build + $(GITBOOK) build stage ./fix-edit-button.sh ./add-relinks.sh @@ -42,7 +42,7 @@ test: ./check-line-length.sh serve: node_modules/gitbook - cd stage && $(GITBOOK) serve + $(GITBOOK) serve stage node_modules/gitbook: npm install gitbook@0.7.1 From 2ab4df6e9aacc2be589dc623d3cc2f051237f2bf Mon Sep 17 00:00:00 2001 From: Mike Morearty Date: Mon, 15 Dec 2014 09:29:45 -0800 Subject: [PATCH 0003/1122] Pipes example: update comments The comments referred to some obsolete method names. Also, fixed a spelling mistake. --- examples/process/pipe/pipe.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index b2d24e5f02..24f1ad6fc4 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -12,7 +12,7 @@ fn main() { { // The `stdin` field has type `Option` - // `take_unwrap` will take the value wrapped in a `Some` variant + // `take` will take the value out of an `Option`, leaving `None` in its place // Note that we take ownership of `stdin` here let mut stdin = process.stdin.take().unwrap(); @@ -22,13 +22,13 @@ fn main() { Ok(_) => println!("sent pangram to wc"), } - // `stdin` gets `drop`ed her, and the pipe is closed + // `stdin` gets `drop`ed here, and the pipe is closed // This is very important, otherwise `wc` wouldn't start processing the // input we just sent } // The `stdout` field also has type `Option` - // the `get_mut_ref` method will return a mutable reference to the value + // the `as_mut` method will return a mutable reference to the value // wrapped in a `Some` variant match process.stdout.as_mut().unwrap().read_to_string() { Err(why) => panic!("couldn't read wc stdout: {}", why.desc), From 50ba4afe36219f079cefcd8c5912b6bc26ef121e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 15 Dec 2014 12:45:34 -0500 Subject: [PATCH 0004/1122] Remove proc() and tuple methods This now builds with HEAD Rust --- examples/channels/channels.rs | 2 +- examples/process/pipe/pipe.rs | 4 +++- examples/staging/test/unit-test.rs | 4 ++-- examples/tasks/tasks.rs | 2 +- examples/tuples/tuples.rs | 4 ++-- src/update.rs | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index cd9a333dc4..8149065631 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -13,7 +13,7 @@ fn main() { let task_tx = tx.clone(); // Each task will send its id via the channel - spawn(proc() { + spawn(move || { // The task takes ownership over `task_tx` // Each task queues a message in the channel task_tx.send(id); diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index 24f1ad6fc4..c2744bf5e8 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -12,7 +12,9 @@ fn main() { { // The `stdin` field has type `Option` - // `take` will take the value out of an `Option`, leaving `None` in its place + // `take` will take the value out of an `Option`, leaving `None` in + // its place. + // // Note that we take ownership of `stdin` here let mut stdin = process.stdin.take().unwrap(); diff --git a/examples/staging/test/unit-test.rs b/examples/staging/test/unit-test.rs index 14a9ff7f03..535ef88bcd 100644 --- a/examples/staging/test/unit-test.rs +++ b/examples/staging/test/unit-test.rs @@ -4,8 +4,8 @@ use std::num::Float; fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { ( - (b.val0().powi(2) - a.val0().powi(2)) + - (b.val1().powi(2) - a.val1().powi(2)) + (b.0.powi(2) - a.0.powi(2)) + + (b.1.powi(2) - a.1.powi(2)) ).sqrt() } diff --git a/examples/tasks/tasks.rs b/examples/tasks/tasks.rs index d1cafaaf63..8f70e3268e 100644 --- a/examples/tasks/tasks.rs +++ b/examples/tasks/tasks.rs @@ -4,7 +4,7 @@ static NTASKS: int = 10; fn main() { for i in range(0, NTASKS) { // Spin up another task - spawn(proc() { + spawn(move || { println!("this is task number {}", i) }); } diff --git a/examples/tuples/tuples.rs b/examples/tuples/tuples.rs index 1721294e5c..88cb27180a 100644 --- a/examples/tuples/tuples.rs +++ b/examples/tuples/tuples.rs @@ -14,8 +14,8 @@ fn main() { 'a', true); // Values can be extracted from the tuple using the `valN` methods - println!("long tuple first value: {}", long_tuple.val0()); - println!("long tuple second value: {}", long_tuple.val1()); + println!("long tuple first value: {}", long_tuple.0); + println!("long tuple second value: {}", long_tuple.1); // Tuples can be tuple members let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); diff --git a/src/update.rs b/src/update.rs index 181e3919e8..aa58a7ecb4 100644 --- a/src/update.rs +++ b/src/update.rs @@ -22,7 +22,7 @@ fn main() { let tx = tx.clone(); let count = example.count(); - spawn(proc() { + spawn(move || { example.process(vec!(i + 1), tx, 0, String::new()); }); From 82a749047d1ed4d9218809bea56a4ad900e4f81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Wed, 17 Dec 2014 00:00:49 +0100 Subject: [PATCH 0005/1122] Fix syntax highlighting disappearing on page refresh. Close #194. --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 0772db4265..22b13b1910 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -66,6 +66,8 @@ function initEditor() { runProgram(program, handleResult); }; + ace.config.setModuleUrl('ace/mode/rust', '/gitbook/plugins/gitbook-plugin-rust-playpen/mode-rust.js'); + editor.setTheme("ace/theme/tomorrow"); editor.getSession().setMode("ace/mode/rust"); editor.setShowPrintMargin(false); From b0ba3d83dc205d93454a408ca1ec17cdf506155c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 16 Dec 2014 18:48:23 -0500 Subject: [PATCH 0006/1122] Fix broken build Thanks https://github.com/rust-lang/rust/commit/0669a432a2e09ad08886cb2138dbe9f5d681fb7f --- examples/generics/phantom/units/units.rs | 27 +++++++++++++----------- examples/ops/operator.rs | 4 ++-- examples/staging/macros/dry.rs | 5 +++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index 134f45ea28..798a12b5b9 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -1,11 +1,11 @@ // Null enumerations to define unit types -#[deriving(Show)] +#[deriving(Show, Copy)] enum Inch {} -#[deriving(Show)] +#[deriving(Show, Copy)] enum Mm {} // Length is phantom type with hidden parameter `Unit` -#[deriving(Show)] +#[deriving(Show, Copy)] struct Length(T,); // `impl X for Y {}` reads "implement `X` Trait for Type `Y`" @@ -17,12 +17,12 @@ struct Length(T,); // This means that this `impl` defines `Add` only for `T` when // two `T's` can be added together and the result is of // Type `T`: (`T: Add`) -impl > Add, - Length> for Length { - fn add(&self, r: &Length) -> Length { - let &Length(ref left) = self; - let &Length(ref right) = r; - +impl + Copy> Add, + Length> for Length { + fn add(self, r: Length) -> Length { + let Length(ref left) = self; + let Length(ref right) = r; + Length(*left + *right) } } @@ -32,10 +32,13 @@ fn main() { let one_foot: Length = Length(12.0); // one_meter has hidden parameter `Mm` let one_meter: Length = Length(1000.0); - + + let two_feet = one_foot + one_foot; + let two_meters = one_meter + one_meter; + // Addition works - println!("one foot + one_foot = {}", one_foot + one_foot); - println!("one meter + one_meter = {}", one_meter + one_meter); + println!("one foot + one_foot = {}", two_feet); + println!("one meter + one_meter = {}", two_meters); // Nonsensical operations fail as they should // Error: type mismatch diff --git a/examples/ops/operator.rs b/examples/ops/operator.rs index 7efb7839ab..79281fde74 100644 --- a/examples/ops/operator.rs +++ b/examples/ops/operator.rs @@ -12,7 +12,7 @@ struct BarFoo; // * U is the type of the sum // This block implements the operation: Foo + Bar = FooBar impl Add for Foo { - fn add(&self, _rhs: &Bar) -> FooBar { + fn add(self, _rhs: Bar) -> FooBar { println!("> Foo.add(&Bar) was called"); FooBar @@ -22,7 +22,7 @@ impl Add for Foo { // Addition can be implemented in a non-commutative way // This block implements the operation: Bar + Foo = BarFoo impl Add for Bar { - fn add(&self, _rhs: &Foo) -> BarFoo { + fn add(self, _rhs: Foo) -> BarFoo { println!("> Bar.add(&Foo) was called"); BarFoo diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry.rs index 20ea95add8..f2a7efaf15 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry.rs @@ -13,11 +13,12 @@ macro_rules! assert_equal_len { macro_rules! op { ($func:ident, $bound:ident, $op:tt, $method:ident) => { - fn $func>(xs: &mut Vec, ys: &Vec) { + fn $func + Copy>(xs: &mut Vec, ys: &Vec) { assert_equal_len!(xs, ys, $func, $op); for (x, y) in xs.iter_mut().zip(ys.iter()) { - *x = x.$method(y); + *x = $bound::$method(*x, *y); + // *x = x.$method(*y); } } } From ef5a4942be55ecd0119621052956c74c8c42beb4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 17 Dec 2014 22:13:36 -0500 Subject: [PATCH 0007/1122] Manually grab `ace` to use latest gitbook --- Makefile | 2 +- node_modules/gitbook-plugin-rust-playpen/index.js | 1 + setup-stage.sh | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0bd3663950..d00b91f2b2 100644 --- a/Makefile +++ b/Makefile @@ -45,4 +45,4 @@ serve: node_modules/gitbook $(GITBOOK) serve stage node_modules/gitbook: - npm install gitbook@0.7.1 + npm install gitbook diff --git a/node_modules/gitbook-plugin-rust-playpen/index.js b/node_modules/gitbook-plugin-rust-playpen/index.js index 19cf6b464f..bbaa5b886c 100644 --- a/node_modules/gitbook-plugin-rust-playpen/index.js +++ b/node_modules/gitbook-plugin-rust-playpen/index.js @@ -5,6 +5,7 @@ module.exports = { "editor.css" ], js: [ + "ace/ace.js", "editor.js", "mode-rust.js" ] diff --git a/setup-stage.sh b/setup-stage.sh index 8d4ff232fd..e5e46bb9f0 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -1,4 +1,11 @@ +#!/bin/dash + +ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min-noconflict' +ace_local_folder='node_modules/gitbook-plugin-rust-playpen/book/ace' + mkdir -p bin mkdir -p stage/node_modules +svn checkout ${ace_repository} ${ace_local_folder} + ln -sf ../book.json stage ln -sf ../examples/README.md stage From 9740c9cc97d82083219239c8ec2179ecdf45ce81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Fro=C5=82ow?= Date: Thu, 18 Dec 2014 14:24:34 +0100 Subject: [PATCH 0008/1122] fix: cannot borrow immutable local variable `collected_iterator` as mutable --- examples/vec/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vec/vec.rs b/examples/vec/vec.rs index eece857b64..52ab96c3ef 100644 --- a/examples/vec/vec.rs +++ b/examples/vec/vec.rs @@ -1,6 +1,6 @@ fn main() { // Iterators can be collected into vectors - let collected_iterator: Vec = range(0i, 10).collect(); + let mut collected_iterator: Vec = range(0i, 10).collect(); println!("Collected range(0, 10) into: {}", collected_iterator); // The `vec!` macro can be used to initialize a vector From 9aee4f504181324b6b6042c7a20ceba23040f734 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 20 Dec 2014 02:38:35 -0800 Subject: [PATCH 0009/1122] Many things, mostly updating to lastest rustc Makefile: No more writing out the entirety of the command when you `make test` super/super.rs: Minor compile fix (forgot a semicolon) Macros: Added a semicolon where it is needed now src/markdown.rs: src is now an Option<&str>, so we'll unwrap it --- Makefile | 2 +- examples/mod/super/super.rs | 2 +- examples/staging/macros/designators.rs | 4 ++-- examples/staging/macros/dry.rs | 12 ++++++------ examples/staging/simd/simd_add.rs | 4 ++-- src/markdown.rs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 0bd3663950..732a026395 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ clean: rm -rf bin stage test: - $(foreach src,$(srcs),$(RUSTC_NT) $(src) || exit;) + @$(foreach src,$(srcs),$(RUSTC_NT) $(src) || exit;) ./check-line-length.sh serve: node_modules/gitbook diff --git a/examples/mod/super/super.rs b/examples/mod/super/super.rs index 6fe3482053..7f6a800659 100644 --- a/examples/mod/super/super.rs +++ b/examples/mod/super/super.rs @@ -23,7 +23,7 @@ mod my { // `self` refers to the current module scope, in this case: `my` use self::cool::function as my_cool_function; - print!("> ") + print!("> "); my_cool_function(); } diff --git a/examples/staging/macros/designators.rs b/examples/staging/macros/designators.rs index 0b88855b19..a8c1928ca7 100644 --- a/examples/staging/macros/designators.rs +++ b/examples/staging/macros/designators.rs @@ -13,8 +13,8 @@ macro_rules! create_function { } } -create_function!(foo) -create_function!(bar) +create_function!(foo); +create_function!(bar); macro_rules! print_result { // the `expr` designator is used for expressions diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry.rs index f2a7efaf15..ec53c50a9f 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry.rs @@ -25,9 +25,9 @@ macro_rules! op { } // implement add_assign, mul_assign, and sub_assign functions -op!(add_assign, Add, +=, add) -op!(mul_assign, Mul, *=, mul) -op!(sub_assign, Sub, -=, sub) +op!(add_assign, Add, +=, add); +op!(mul_assign, Mul, *=, mul); +op!(sub_assign, Sub, -=, sub); fn main() { let mut xs = Vec::from_elem(5, 0f64); @@ -56,7 +56,7 @@ mod test { } // test add_assign, mul_assign and sub_assign - test!(add_assign, 1u, 2u, 3u) - test!(mul_assign, 2u, 3u, 6u) - test!(sub_assign, 3u, 2u, 1u) + test!(add_assign, 1u, 2u, 3u); + test!(mul_assign, 2u, 3u, 6u); + test!(sub_assign, 3u, 2u, 1u); } diff --git a/examples/staging/simd/simd_add.rs b/examples/staging/simd/simd_add.rs index 8c154a8aaf..766bf7a326 100644 --- a/examples/staging/simd/simd_add.rs +++ b/examples/staging/simd/simd_add.rs @@ -71,6 +71,6 @@ mod bench { } } - bench!(vanilla, add_assign) - bench!(simd, simd_add_assign) + bench!(vanilla, add_assign); + bench!(simd, simd_add_assign); } diff --git a/src/markdown.rs b/src/markdown.rs index 811027992f..a69326cd16 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -95,7 +95,7 @@ impl<'a, 'b> Markdown<'a, 'b> { Some(captures) => { let src = captures.at(1); let input = format!("{{{}.out}}", src); - let s = try!(file::run(prefix, id, src)); + let s = try!(file::run(prefix, id, src.unwrap())); let s = format!("```\n$ rustc {0}.rs && ./{0}\n{1}```", src, s); From 4b8e4d050a9e35a49eacea7686e6924002baadfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Fri, 19 Dec 2014 21:53:38 +0100 Subject: [PATCH 0010/1122] Fix doubled request to the playpen on pages with an editor when accessed directly --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 22b13b1910..189f1c6af2 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -112,8 +112,6 @@ function initEditor() { }); } -initEditor(); - require(["gitbook"], function(gitbook) { gitbook.events.bind("page.change", function() { initEditor(); From ad2cd0f51baa119e7cd28b80a36351c42696fdd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Thu, 18 Dec 2014 14:36:33 +0100 Subject: [PATCH 0011/1122] Fix a couple 404s, and a missing space in a ref. link --- examples/hof/input.md | 2 +- examples/staging/hash/hashset/input.md | 2 +- examples/structs/input.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/hof/input.md b/examples/hof/input.md index 02784bbe0e..2183b618d9 100644 --- a/examples/hof/input.md +++ b/examples/hof/input.md @@ -9,5 +9,5 @@ and [Iterator][iter] implement their fair share of HOFs. -[option]: http://doc.rust-lang.org/core/option/type.Option.html +[option]: http://doc.rust-lang.org/core/option/enum.Option.html [iter]: http://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/staging/hash/hashset/input.md b/examples/staging/hash/hashset/input.md index 535c43414b..592628e026 100644 --- a/examples/staging/hash/hashset/input.md +++ b/examples/staging/hash/hashset/input.md @@ -35,4 +35,4 @@ Try all of these in the following example. (Examples adapted from the [documentation.][hash-set]) [treeset]: http://doc.rust-lang.org/std/collections/struct.TreeSet.html -[hash-set]: http://doc.rust-lang.org/std/collections/hashmap/struct.HashSet.html#method.difference +[hash-set]: http://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference diff --git a/examples/structs/input.md b/examples/structs/input.md index 903a625f4e..10190d6d08 100644 --- a/examples/structs/input.md +++ b/examples/structs/input.md @@ -7,4 +7,4 @@ There are three types of structures ("structs") that can be created using the {structs.play} -[1]:http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[1]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) From 8ffab26aba06c4e7c1e37f93a5fe1ed8dd4e618c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Sat, 20 Dec 2014 16:31:49 +0100 Subject: [PATCH 0012/1122] Replace the escapeHTML() by a more efficient one --- .../book/editor.css | 1 + .../book/editor.js | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index 6471ce2dc5..f3bcdd9096 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -26,6 +26,7 @@ display: none; border-radius: 4px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + white-space: pre; } #reset-code { diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 0772db4265..b645e4588c 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -129,14 +129,26 @@ function updateEditorHeight() { editor.resize(); }; +// +// escapeHTML() borrowed from mustache.js: +// https://github.com/janl/mustache.js/blob/master/mustache.js#L43 +// +// via: +// http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery/12034334#12034334 +// +var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''', + "/": '/' +}; + function escapeHTML(unsafe) { - return unsafe - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'") - .replace(newLineRegex, '
'); + return String(unsafe).replace(/[&<>"'\/]/g, function(s) { + return entityMap[s]; + }); } // Dispatches a XMLHttpRequest to the Rust playpen, running the program, and From bd9e3bc3f7fe71648c03867c3622897a2f5ced38 Mon Sep 17 00:00:00 2001 From: Yang-Le Date: Sun, 21 Dec 2014 01:37:56 -0500 Subject: [PATCH 0013/1122] Fix site generation & update spawn usage --- examples/channels/channels.rs | 5 +++-- examples/tasks/tasks.rs | 6 ++++-- src/markdown.rs | 9 +++++---- src/update.rs | 5 +++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 8149065631..4d53f99172 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -1,4 +1,5 @@ use std::comm; +use std::thread::Thread; static NTASKS: uint = 3; @@ -13,7 +14,7 @@ fn main() { let task_tx = tx.clone(); // Each task will send its id via the channel - spawn(move || { + Thread::spawn(move || { // The task takes ownership over `task_tx` // Each task queues a message in the channel task_tx.send(id); @@ -21,7 +22,7 @@ fn main() { // Sending is a non-blocking operation, the task will continue // immediately after sending its message println!("task {} finished", id); - }); + }).detach(); } // Here, all the messages are collected diff --git a/examples/tasks/tasks.rs b/examples/tasks/tasks.rs index 8f70e3268e..43f5622219 100644 --- a/examples/tasks/tasks.rs +++ b/examples/tasks/tasks.rs @@ -1,11 +1,13 @@ +use std::thread::Thread; + static NTASKS: int = 10; // This is the `main` task fn main() { for i in range(0, NTASKS) { // Spin up another task - spawn(move || { + Thread::spawn(move || { println!("this is task number {}", i) - }); + }).detach(); } } diff --git a/src/markdown.rs b/src/markdown.rs index a69326cd16..51d58925a4 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -53,7 +53,7 @@ impl<'a, 'b> Markdown<'a, 'b> { match re.captures(line) { None => {}, Some(captures) => { - let src = captures.at(1); + let src = captures.at(1).unwrap(); let input = format!("{{{}}}", src); let p = format!("examples/{}/{}/{}", prefix, id, src); let output = match file::read(&Path::new(p.as_slice())) { @@ -62,7 +62,7 @@ impl<'a, 'b> Markdown<'a, 'b> { }, Ok(string) => { format!("``` rust\n// {}\n{}```", - captures.at(1), string) + src, string) } }; @@ -129,8 +129,9 @@ impl<'a, 'b> Markdown<'a, 'b> { once_ = true; } - let input = format!("{{{}.play}}", captures.at(1)); - let src = format!("{}.rs", captures.at(1)); + let srcbase = captures.at(1).unwrap(); + let input = format!("{{{}.play}}", srcbase); + let src = format!("{}.rs", srcbase); let p = format!("examples/{}/{}/{}", prefix, id, src); let output = match file::read(&Path::new(p.as_slice())) { Err(_) => { diff --git a/src/update.rs b/src/update.rs index aa58a7ecb4..3eb75b011a 100644 --- a/src/update.rs +++ b/src/update.rs @@ -7,6 +7,7 @@ extern crate regex_macros; extern crate serialize; use example::Example; +use std::thread::Thread; mod example; mod file; @@ -22,9 +23,9 @@ fn main() { let tx = tx.clone(); let count = example.count(); - spawn(move || { + Thread::spawn(move || { example.process(vec!(i + 1), tx, 0, String::new()); - }); + }).detach(); nexamples += count; } From 7d4a6aab15185e28380e911c10ba791e2dc5cfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Sun, 21 Dec 2014 22:09:29 +0100 Subject: [PATCH 0014/1122] Check the size of the response before appending it to the DOM. Close #177 --- .../gitbook-plugin-rust-playpen/book/editor.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 22b13b1910..e97f7daaf0 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -40,6 +40,9 @@ var Range; // Original source code var originalCode; +// Maximum length of a response before it has to be truncated +var MAX_RESPONSE_LENGTH = 50000; + function initEditor() { // Fetching DOM items editorDiv = document.getElementById("editor"); @@ -181,6 +184,15 @@ function runProgram(program, callback) { // The callback to runProgram function handleResult(statusCode, message) { + + // Check the size of the message, shorten it if + // it's too big to be appended to the DOM. + if ( message.length > MAX_RESPONSE_LENGTH ) { + message = message.slice(0, MAX_RESPONSE_LENGTH / 2) + + '\n\n--- THIS RESULT HAS BEEN SHORTENED ---\n\n' + + message.slice(-MAX_RESPONSE_LENGTH / 2); + } + // Dispatch depending on result type if (result == null) { resultDiv.style.backgroundColor = errorColor; From 1946351bdae1f43e2fc24cc3f13a0c3cd1095e4c Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sun, 21 Dec 2014 19:06:20 -0800 Subject: [PATCH 0015/1122] Fixes bounds.rs, changes ops.rs to be correct First of all, change Add and Sub to take by value, not reference. Second, reverts part of PR #260, because that person made the dot product into a multiplication operation, which shouldn't have ever happened. Also changes the description for ops.rs. Also fixes #347 --- examples/bounds/bounds.rs | 15 +++++++-------- examples/ops/input.md | 5 ++--- examples/ops/operator.rs | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index 3fc12fe4e8..7aaf339ddf 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -1,4 +1,4 @@ -#[deriving(Show)] +#[deriving(Show, Copy)] struct Vec2 { x: T, y: T, @@ -9,10 +9,10 @@ impl< T: Add > Add, Vec2> for Vec2 { - fn add(&self, rhs: &Vec2) -> Vec2 { + fn add(self, rhs: Vec2) -> Vec2 { Vec2 { // `x` and `y` are of type `T`, and implement the `add` method - x: self.x.add(&rhs.x), + x: self.x.add(rhs.x), // The sugary `+` operator can also be used y: self.y + rhs.y, } @@ -24,7 +24,7 @@ impl< T: Sub > Sub, Vec2> for Vec2 { - fn sub(&self, rhs: &Vec2) -> Vec2 { + fn sub(self, rhs: Vec2) -> Vec2 { Vec2 { x: self.x - rhs.x, y: self.y - rhs.y, @@ -35,9 +35,8 @@ for Vec2 { impl< // Bound: `T` must implement *both* the `Add` trait and the `Mul` trait T: Add + Mul -> Mul, T> -for Vec2 { - fn mul(&self, rhs: &Vec2) -> T { +> Vec2 { + fn dot(self, rhs: Vec2) -> T { (self.x * rhs.x) + (self.y * rhs.y) } } @@ -49,7 +48,7 @@ fn main() { println!("{} + {} = {}", v1, v2, v1 + v2); println!("{} - {} = {}", v1, v2, v1 - v2); - println!("{} . {} = {}", v1, v2, v1.dot(&v2)); + println!("{} ⋅ {} = {}", v1, v2, v1.dot(v2)); // Error! `char` doesn't implement the `Add` trait println!("{}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' }); diff --git a/examples/ops/input.md b/examples/ops/input.md index 8c0c066d73..e6098704a1 100644 --- a/examples/ops/input.md +++ b/examples/ops/input.md @@ -1,11 +1,10 @@ In Rust, many of the operators can be overloaded via traits. This is possible because operators are just sugar for method calls. For example, `a + b` -desugars to `a.add(&b)`. This `add` method is part of the `Add` trait, hence +desugars to `a.add(b)`. This `add` method is part of the `Add` trait, hence any implementor of the `Add` trait will be able to use the `+` operator. {operator.play} -Here is a [list][ops] of -the traits that overload operators. +Here is a [list][ops] of the traits that overload operators. [ops]: http://doc.rust-lang.org/core/ops/ diff --git a/examples/ops/operator.rs b/examples/ops/operator.rs index 79281fde74..3b12423d9b 100644 --- a/examples/ops/operator.rs +++ b/examples/ops/operator.rs @@ -13,7 +13,7 @@ struct BarFoo; // This block implements the operation: Foo + Bar = FooBar impl Add for Foo { fn add(self, _rhs: Bar) -> FooBar { - println!("> Foo.add(&Bar) was called"); + println!("> Foo.add(Bar) was called"); FooBar } @@ -23,7 +23,7 @@ impl Add for Foo { // This block implements the operation: Bar + Foo = BarFoo impl Add for Bar { fn add(self, _rhs: Foo) -> BarFoo { - println!("> Bar.add(&Foo) was called"); + println!("> Bar.add(Foo) was called"); BarFoo } From 6e61723a2c5402cd08fecc5b18832c84f731f18b Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sun, 21 Dec 2014 23:14:35 -0800 Subject: [PATCH 0016/1122] Fix vec.rs Change a mutable vector to immutable, added a ; at the end of a println!() --- examples/vec/vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vec/vec.rs b/examples/vec/vec.rs index 52ab96c3ef..b960cbd134 100644 --- a/examples/vec/vec.rs +++ b/examples/vec/vec.rs @@ -1,6 +1,6 @@ fn main() { // Iterators can be collected into vectors - let mut collected_iterator: Vec = range(0i, 10).collect(); + let collected_iterator: Vec = range(0i, 10).collect(); println!("Collected range(0, 10) into: {}", collected_iterator); // The `vec!` macro can be used to initialize a vector @@ -8,7 +8,7 @@ fn main() { println!("Initial vector: {}", xs); // Insert new element at the end of the vector - println!("Push 4 into the vector") + println!("Push 4 into the vector"); xs.push(4); println!("Vector: {}", xs); From 2c9230b1e9e3087c158f9c2b9db6eca4e1c1f304 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sun, 21 Dec 2014 23:36:03 -0800 Subject: [PATCH 0017/1122] Merge mdinger/rust-by-example fix-bounds --- examples/bounds/bounds.rs | 24 ++++++++++-------------- examples/bounds/input.md | 5 +++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index 7aaf339ddf..83a11a84d5 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -4,11 +4,10 @@ struct Vec2 { y: T, } -impl< - // Bound: `T` must implement the `Add` trait - T: Add -> Add, Vec2> -for Vec2 { +// Apply bound to `T` at first instance of `T`. `T` +// must implement the `Add` trait. +impl> Add, Vec2> + for Vec2 { fn add(self, rhs: Vec2) -> Vec2 { Vec2 { // `x` and `y` are of type `T`, and implement the `add` method @@ -19,11 +18,9 @@ for Vec2 { } } -impl< - // Bound: `T` must implement the `Sub` trait - T: Sub -> Sub, Vec2> -for Vec2 { +// Bound: `T` must implement the `Sub` trait +impl Sub, Vec2> for Vec2 + where T: Sub { fn sub(self, rhs: Vec2) -> Vec2 { Vec2 { x: self.x - rhs.x, @@ -32,10 +29,9 @@ for Vec2 { } } -impl< - // Bound: `T` must implement *both* the `Add` trait and the `Mul` trait - T: Add + Mul -> Vec2 { +// Bound: `T` must implement *both* the `Add` trait and the `Mul` trait +impl Vec2 + where T: Add + Mul { fn dot(self, rhs: Vec2) -> T { (self.x * rhs.x) + (self.y * rhs.y) } diff --git a/examples/bounds/input.md b/examples/bounds/input.md index 0caf2845d9..fac77fe76e 100644 --- a/examples/bounds/input.md +++ b/examples/bounds/input.md @@ -7,4 +7,9 @@ When working with generics, the type parameters (e.g. `Ty`) may use traits * The generic can only be specialized for type parameters that conform to the bounds. +Bounds are typically applied in one of two ways: + +* At the first instance of the type +* In a `where` clause which directly precedes the `{` in the `impl` + {bounds.play} From e015debf459903fc38f1ffdb90574ad1b9859a06 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Wed, 24 Dec 2014 01:29:07 +0200 Subject: [PATCH 0018/1122] Track Rust master Fix usage of deprecated methods to compile with latest Rust nightly: * parse instead of from_str * std::iter::repeat instead of deprecated StrExt::repeat * per char is_whitespace instead of deprecated StrExt::is_whitespace --- examples/staging/arg/matching/match_args.rs | 2 +- src/example.rs | 11 +++++++---- src/markdown.rs | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/staging/arg/matching/match_args.rs b/examples/staging/arg/matching/match_args.rs index 037f1cab9f..b13c719e0a 100644 --- a/examples/staging/arg/matching/match_args.rs +++ b/examples/staging/arg/matching/match_args.rs @@ -35,7 +35,7 @@ fn main() { // one command and one argument passed [_, ref cmd, ref num] => { // parse the number - let number: int = match from_str(num.as_slice()) { + let number: int = match num.parse() { Some(n) => { n }, diff --git a/src/example.rs b/src/example.rs index acee6504e4..bbddde3f0f 100644 --- a/src/example.rs +++ b/src/example.rs @@ -2,6 +2,7 @@ use file; use markdown::Markdown; use serialize::{Decodable,json}; use std::iter::AdditiveIterator; +use std::iter::repeat; #[deriving(Decodable)] pub struct Example { @@ -46,20 +47,22 @@ impl Example { let entry = match Markdown::process(number.as_slice(), id, title, prefix) { Ok(_) => { - let md = if prefix.as_slice().is_whitespace() { + let md = if prefix.chars().all(|c| c.is_whitespace()) { format!("{}.md", id) } else { format!("{}/{}.md", prefix, id) }; format!("{}* [{}]({})", - " ".repeat(indent), + repeat(" ").take(indent).collect::(), title, md) }, Err(why) => { print!("{}: {}\n", id, why); - format!("{}* {}", " ".repeat(indent), title) + format!("{}* {}", + repeat(" ").take(indent).collect::(), + title) }, }; @@ -74,7 +77,7 @@ impl Example { for (i, example) in children.iter().enumerate() { let tx = tx.clone(); - let prefix = if prefix.as_slice().is_whitespace() { + let prefix = if prefix.chars().all(|c| c.is_whitespace()) { format!("{}", id) } else { format!("{}/{}", prefix, id) diff --git a/src/markdown.rs b/src/markdown.rs index 51d58925a4..829fd694cf 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -1,5 +1,6 @@ use file; use playpen; +use std::iter::repeat; pub struct Markdown<'a, 'b> { content: String, @@ -30,8 +31,9 @@ impl<'a, 'b> Markdown<'a, 'b> { format!("{}", x) }).collect::>().connect("."); + let len = number.len(); let content = format!("{} {} {}\n\n{}", - "#".repeat(number.len()), + repeat("#").take(len).collect::(), version, title, body); From fc41c2e06168784d27e5307660e6fdc6c2016b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dr=C3=A9au?= Date: Wed, 24 Dec 2014 18:45:46 +0100 Subject: [PATCH 0019/1122] Change prompt symbol in comments from $ to %. Close #334 --- examples/fs/fs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 9dd7bbb849..27daa1f6d0 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -2,17 +2,17 @@ use std::io::fs; use std::io::fs::PathExtensions; use std::io::{File, IoResult, USER_RWX}; -// A simple implementation of `$ cat path` +// A simple implementation of `% cat path` fn cat(path: &Path) -> IoResult { File::open(path).and_then(|mut f| f.read_to_string()) } -// A simple implementation of `$ echo s > path` +// A simple implementation of `% echo s > path` fn echo(s: &str, path: &Path) -> IoResult<()> { File::create(path).and_then(|mut f| f.write_str(s)) } -// A simple implementation of `$ touch path` (ignores existing files) +// A simple implementation of `% touch path` (ignores existing files) fn touch(path: &Path) -> IoResult<()> { if !path.exists() { File::create(path).and_then(|_| Ok(())) From ef67809c2648442552f089b01db52d334cffd655 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 24 Dec 2014 22:38:49 +0200 Subject: [PATCH 0020/1122] Update tuples.rs update comment: tuple.val0 -> tuple.0 --- examples/tuples/tuples.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tuples/tuples.rs b/examples/tuples/tuples.rs index 88cb27180a..21a2d0f017 100644 --- a/examples/tuples/tuples.rs +++ b/examples/tuples/tuples.rs @@ -13,7 +13,7 @@ fn main() { 0.1f32, 0.2f64, 'a', true); - // Values can be extracted from the tuple using the `valN` methods + // Values can be extracted from the tuple using the `.N` syntax println!("long tuple first value: {}", long_tuple.0); println!("long tuple second value: {}", long_tuple.1); From 613a4a73a7c5f03d08778539ab8014a1f619cec7 Mon Sep 17 00:00:00 2001 From: Kent English Date: Wed, 24 Dec 2014 19:08:55 -0500 Subject: [PATCH 0021/1122] enums: fix typo - comments still referred to Node in some places --- examples/enum/enum.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/enum/enum.rs b/examples/enum/enum.rs index d3a6171e23..a2b7f8b06e 100644 --- a/examples/enum/enum.rs +++ b/examples/enum/enum.rs @@ -19,7 +19,7 @@ impl List { // Consume a list, and return the same list with a new element at its front fn prepend(self, elem: uint) -> List { - // `Cons` also has type Node + // `Cons` also has type List Cons(elem, box self) } @@ -27,7 +27,7 @@ impl List { fn len(&self) -> uint { // `self` has to be matched, because the behavior of this method // depends on the variant of `self` - // `self` has type `&Node`, and `*self` has type `Node`, matching on a + // `self` has type `&List`, and `*self` has type `List`, matching on a // concrete type `T` is preferred over a match on a reference `&T` match *self { // Can't take ownership of the tail, because `self` is borrowed; From 4611f6b9174a90c865bf764f526dae7c119cb3c9 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Fri, 26 Dec 2014 00:46:04 +0200 Subject: [PATCH 0022/1122] Changes for #358 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rewrite ‘tasks’ example as ‘threads’ * Remove mention of green threads * Fix example to sleep after spawning threads to display prints in browser * Rewrite ‘channels’ to use ‘thread’ in text and code --- examples/channels/channels.rs | 24 ++++++++++++------------ examples/channels/input.md | 2 +- examples/structure.json | 2 +- examples/tasks/input.md | 11 ----------- examples/tasks/tasks.rs | 13 ------------- examples/threads/input.md | 10 ++++++++++ examples/threads/threads.rs | 19 +++++++++++++++++++ 7 files changed, 43 insertions(+), 38 deletions(-) delete mode 100644 examples/tasks/input.md delete mode 100644 examples/tasks/tasks.rs create mode 100644 examples/threads/input.md create mode 100644 examples/threads/threads.rs diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 4d53f99172..53dedba24b 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -1,7 +1,7 @@ use std::comm; use std::thread::Thread; -static NTASKS: uint = 3; +static NTHREADS: uint = 3; fn main() { // Channels have two endpoints: the `Sender` and the `Receiver`, @@ -9,27 +9,27 @@ fn main() { // (type annotation is superfluous) let (tx, rx): (Sender, Receiver) = comm::channel(); - for id in range(0, NTASKS) { + for id in range(0, NTHREADS) { // The sender endpoint can be copied - let task_tx = tx.clone(); + let thread_tx = tx.clone(); - // Each task will send its id via the channel + // Each thread will send its id via the channel Thread::spawn(move || { - // The task takes ownership over `task_tx` - // Each task queues a message in the channel - task_tx.send(id); + // The thread takes ownership over `thread_tx` + // Each thread queues a message in the channel + thread_tx.send(id); - // Sending is a non-blocking operation, the task will continue + // Sending is a non-blocking operation, the thread will continue // immediately after sending its message - println!("task {} finished", id); + println!("thread {} finished", id); }).detach(); } // Here, all the messages are collected - let mut ids = Vec::with_capacity(NTASKS); - for _ in range(0, NTASKS) { + let mut ids = Vec::with_capacity(NTHREADS); + for _ in range(0, NTHREADS) { // The `recv` method picks a message from the channel - // `recv` will block the current task if there no messages available + // `recv` will block the current thread if there no messages available ids.push(rx.recv()); } diff --git a/examples/channels/input.md b/examples/channels/input.md index 7e5186a247..86ac3fb69f 100644 --- a/examples/channels/input.md +++ b/examples/channels/input.md @@ -1,4 +1,4 @@ -Rust provides asynchronous `channels` for communication between tasks. Channels +Rust provides asynchronous `channels` for communication between threads. Channels allow an unidirectional flow of information between two end-points: the `Sender` and the `Receiver`. diff --git a/examples/structure.json b/examples/structure.json index 372e74722c..6ed84b3139 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -89,7 +89,7 @@ { "id": "vec", "title": "Vectors", "children": null }, { "id": "str", "title": "Strings", "children": null }, { "id": "clone", "title": "Clone", "children": null }, - { "id": "tasks", "title": "Tasks", "children": null }, + { "id": "threads", "title": "Threads", "children": null }, { "id": "channels", "title": "Channels", "children": null }, { "id": "timers", "title": "Timers", "children": null }, { "id": "sockets", "title": "Unix sockets", "children": null }, diff --git a/examples/tasks/input.md b/examples/tasks/input.md deleted file mode 100644 index a326cd9441..0000000000 --- a/examples/tasks/input.md +++ /dev/null @@ -1,11 +0,0 @@ -Rust provides a mechanism for spawning lightweight tasks via the `spawn` -function, the argument of this function is an owned closure named `proc`. - -{tasks.play} - -These tasks will be scheduled by the Rust runtime and the order of execution of -these tasks will be non-deterministic. - -(By default, Rust uses its *native* runtime, which maps each Rust task to a -native thread. Rust also provides a *green* runtime that provides green threads -and maps M Rust tasks to N native threads.) diff --git a/examples/tasks/tasks.rs b/examples/tasks/tasks.rs deleted file mode 100644 index 43f5622219..0000000000 --- a/examples/tasks/tasks.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::thread::Thread; - -static NTASKS: int = 10; - -// This is the `main` task -fn main() { - for i in range(0, NTASKS) { - // Spin up another task - Thread::spawn(move || { - println!("this is task number {}", i) - }).detach(); - } -} diff --git a/examples/threads/input.md b/examples/threads/input.md new file mode 100644 index 0000000000..be072180b7 --- /dev/null +++ b/examples/threads/input.md @@ -0,0 +1,10 @@ +Rust provides a mechanism for spawning native OS threads via the `spawn` +function, the argument of this function is a moving closure. + +{threads.play} + +These threads will be scheduled by the OS and the order of execution of +these tasks will be non-deterministic. + +(Currently Rust uses *native* runtime, which maps each Rust task to a +native thread.) diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs new file mode 100644 index 0000000000..b56e21d696 --- /dev/null +++ b/examples/threads/threads.rs @@ -0,0 +1,19 @@ +use std::thread::Thread; +use std::io::timer; +use std::time::duration::Duration; + +static NTHREADS: int = 10; + +// This is the `main` thread +fn main() { + for i in range(0, NTHREADS) { + // Spin up another thread + Thread::spawn(move || { + println!("this is thread number {}", i) + }).detach(); + } + + // Wait for threads to complete + let interval = Duration::milliseconds(1000); + timer::sleep(interval); +} From 51825a118e69954485b35a42cdceab3d26448470 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Sun, 28 Dec 2014 20:46:29 +0200 Subject: [PATCH 0023/1122] Fix shell scripts for MacOS X * grep extended regex syntax since Perl syntax no longer supported * find requires explicit path * sed requires explicit option after empty extension --- check-line-length.sh | 2 +- fix-edit-button.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/check-line-length.sh b/check-line-length.sh index 046f8643ae..902719683a 100755 --- a/check-line-length.sh +++ b/check-line-length.sh @@ -7,7 +7,7 @@ WHITELIST=( echo "Checking if any rust file has a line longer than 79 characters" -suspects=$(find -name '*.rs' | xargs grep -Pl ".{80}") +suspects=$(find . -name '*.rs' | xargs grep -El ".{80}") status=$? any_offender=false diff --git a/fix-edit-button.sh b/fix-edit-button.sh index 06c292071e..0c3baefaa0 100755 --- a/fix-edit-button.sh +++ b/fix-edit-button.sh @@ -5,6 +5,6 @@ for example in $(find examples -type d -name "*"); do if [[ -f ${html} ]]; then echo ${html} - sed -i s:${example#examples/}.md:${example}/input.md: ${html} + sed -i -e s:${example#examples/}.md:${example}/input.md: ${html} fi done From 18ed15424d05aecb1d2d6368c271a12bc208bbfe Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Sun, 28 Dec 2014 21:42:14 +0200 Subject: [PATCH 0024/1122] threads: join threads instead of sleeping --- examples/threads/threads.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index b56e21d696..4ba8e25e1b 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,6 +1,4 @@ use std::thread::Thread; -use std::io::timer; -use std::time::duration::Duration; static NTHREADS: int = 10; @@ -8,12 +6,8 @@ static NTHREADS: int = 10; fn main() { for i in range(0, NTHREADS) { // Spin up another thread - Thread::spawn(move || { + let _ = Thread::spawn(move || { println!("this is thread number {}", i) - }).detach(); + }).join(); } - - // Wait for threads to complete - let interval = Duration::milliseconds(1000); - timer::sleep(interval); } From 0de459f7428595d258aa53ace832775d7884c194 Mon Sep 17 00:00:00 2001 From: Thomas Galvin Date: Fri, 2 Jan 2015 18:03:36 +0000 Subject: [PATCH 0025/1122] attribute: fixing Markdown link --- examples/attribute/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/attribute/input.md b/examples/attribute/input.md index cf7f90fff1..13c3a051a2 100644 --- a/examples/attribute/input.md +++ b/examples/attribute/input.md @@ -3,7 +3,7 @@ can be used to/for: * [conditional compilation of code][cfg] -* [set crate name, version and type (binary or library)][config] +* [set crate name, version and type (binary or library)][crate] * disable [lints][lint] (warnings) * enable compiler features (macros, glob imports, etc.) * link to a foreign library From acd6bcdb7459f5b28126952041323c273a7ff27e Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 3 Jan 2015 12:54:21 -0800 Subject: [PATCH 0026/1122] Update to latest rustc * change from `Vec::from_elem(x, y)` to `iter::repeat(y).take(x).collect()` * change from `task_rng` to `thread_rng` * change from `trim_chars` to `trim_matches` --- examples/staging/macros/dry.rs | 5 +++-- examples/staging/rand/deriving.rs | 2 +- examples/staging/rand/distributions.rs | 2 +- examples/staging/rand/gen.rs | 2 +- examples/str/str.rs | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry.rs index ec53c50a9f..8ac526c9c5 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry.rs @@ -1,4 +1,5 @@ #![feature(macro_rules)] +use std::iter; macro_rules! assert_equal_len { ($a:ident, $b: ident, $func:ident, $op:tt) => { @@ -30,8 +31,8 @@ op!(mul_assign, Mul, *=, mul); op!(sub_assign, Sub, -=, sub); fn main() { - let mut xs = Vec::from_elem(5, 0f64); - let ys = Vec::from_elem(6, 1f64); + let mut xs = iter::repeat(0f64).take(5).collect(); + let ys = iter::repeat(1f64).take(6).collect(); // this operation will fail at runtime add_assign(&mut xs, &ys); diff --git a/examples/staging/rand/deriving.rs b/examples/staging/rand/deriving.rs index 809b7bf9e8..36358f46bf 100644 --- a/examples/staging/rand/deriving.rs +++ b/examples/staging/rand/deriving.rs @@ -14,7 +14,7 @@ struct Rectangle { } fn main() { - let mut rng = rand::task_rng(); + let mut rng = rand::thread_rng(); println!("random point\n{}", rng.gen::()); println!("random rectangle\n{}", rng.gen::()); diff --git a/examples/staging/rand/distributions.rs b/examples/staging/rand/distributions.rs index e1021d5fa5..32058305f0 100644 --- a/examples/staging/rand/distributions.rs +++ b/examples/staging/rand/distributions.rs @@ -2,7 +2,7 @@ use std::rand::distributions::{IndependentSample,Normal,StudentT}; use std::rand; fn main() { - let mut rng = rand::task_rng(); + let mut rng = rand::thread_rng(); let normal = Normal::new(0.0, 1.0); println!("10 samples from a normal distribution with mean 0.0 and SD 1.0"); diff --git a/examples/staging/rand/gen.rs b/examples/staging/rand/gen.rs index e599426892..a6fb3d87dc 100644 --- a/examples/staging/rand/gen.rs +++ b/examples/staging/rand/gen.rs @@ -3,7 +3,7 @@ use std::rand; fn main() { // create a task-local Random Number Generator - let mut rng = rand::task_rng(); + let mut rng = rand::thread_rng(); // the `gen` methods generates values in the full range of each type using // a uniform distribution diff --git a/examples/str/str.rs b/examples/str/str.rs index e0743a5b5c..4566337c6b 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -27,7 +27,7 @@ fn main() { // The trimmed string is a slice to the original string, hence no new // allocation is performed let chars_to_trim: &[char] = &[' ', ',']; - let trimmed_str: &str = string.as_slice().trim_chars(chars_to_trim); + let trimmed_str: &str = string.as_slice().trim_matches(chars_to_trim); println!("Used characters: {}", trimmed_str); // Heap allocate a string From 2d367cef68d35ef62287f7029071200296663b2b Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sun, 4 Jan 2015 10:48:57 +0100 Subject: [PATCH 0027/1122] array: Upgrade to new fixed-length array syntax --- examples/array/array.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/array/array.rs b/examples/array/array.rs index 25aa3eeb5f..bf55fc267b 100644 --- a/examples/array/array.rs +++ b/examples/array/array.rs @@ -8,10 +8,10 @@ fn analyze_slice(slice: &[int]) { fn main() { // Fixed-size array (type signature is superfluous) - let xs: [int, ..5] = [1, 2, 3, 4, 5]; + let xs: [int; 5] = [1, 2, 3, 4, 5]; // All elements can be initialized to the same value - let ys: [int, ..500] = [0, ..500]; + let ys: [int; 500] = [0; 500]; // Indexing starts at 0 println!("first element of the array: {}", xs[0]); From 2f2bf056519175098fe3176cb6788642f07fcae5 Mon Sep 17 00:00:00 2001 From: Luke Gallagher Date: Mon, 5 Jan 2015 12:13:26 +1100 Subject: [PATCH 0028/1122] channels: `std::comm` moved to `std::sync::mpsc` --- examples/channels/channels.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 53dedba24b..5285afbb6a 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -1,4 +1,5 @@ -use std::comm; +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; use std::thread::Thread; static NTHREADS: uint = 3; @@ -7,7 +8,7 @@ fn main() { // Channels have two endpoints: the `Sender` and the `Receiver`, // where `T` is the type of the message to be transfer // (type annotation is superfluous) - let (tx, rx): (Sender, Receiver) = comm::channel(); + let (tx, rx): (Sender, Receiver) = mpsc::channel(); for id in range(0, NTHREADS) { // The sender endpoint can be copied @@ -17,7 +18,7 @@ fn main() { Thread::spawn(move || { // The thread takes ownership over `thread_tx` // Each thread queues a message in the channel - thread_tx.send(id); + thread_tx.send(id).unwrap(); // Sending is a non-blocking operation, the thread will continue // immediately after sending its message From 4180afdad06aad3c559f48efe6bf54bf8994aeee Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Tue, 6 Jan 2015 22:49:38 -0800 Subject: [PATCH 0029/1122] README.md: add proper instructions on nodejs --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f81844762f..64d7bc4beb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ See [CONTRIBUTING.md][how-to-contribute]. ## How to generate the static site +First, make certain you install `nodejs` on Debian based distributions, or +`node` on non-Debian distros. After installation, if you use a Debian based +distro (i.e. Ubuntu), run + + sudo ln -s /usr/bin/nodejs /usr/bin/node + +Then run + ``` make all make book @@ -20,8 +28,6 @@ make test View the results with `make serve`. -Note: on Ubuntu `node` may be called `nodejs`. I had to edit `.bin/gitbook` accordingly. - ### Details We use these tools to generate the static site: From e9a991e866b5882b01f173792bd9812b2959323a Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Wed, 7 Jan 2015 13:37:26 -0800 Subject: [PATCH 0030/1122] Allow '$' in rust files --- src/playpen.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/playpen.rs b/src/playpen.rs index 8fd114903d..ff3e1a2c9f 100644 --- a/src/playpen.rs +++ b/src/playpen.rs @@ -12,6 +12,7 @@ fn escape(source: &str) -> String { for chr in source.trim().chars() { match chr { + '$' => s.push_str("$"), '*' => s.push_str("*"), '<' => s.push_str("<"), '>' => s.push_str(">"), From a41e8be8c6e0712ab5c1115c53a8cdcf8d53b52a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 7 Jan 2015 22:48:18 -0200 Subject: [PATCH 0031/1122] Fix ops example according to latest nightly --- examples/ops/operator.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/ops/operator.rs b/examples/ops/operator.rs index 79281fde74..c6cd2e752b 100644 --- a/examples/ops/operator.rs +++ b/examples/ops/operator.rs @@ -1,17 +1,21 @@ +use std::ops::Add; + struct Foo; struct Bar; -#[deriving(Show)] +#[derive(Show)] struct FooBar; -#[deriving(Show)] +#[derive(Show)] struct BarFoo; // The `Add` trait needs two generic parameters: // * T is the type of the RHS summand, and // * U is the type of the sum // This block implements the operation: Foo + Bar = FooBar -impl Add for Foo { +impl Add for Foo { + type Output = FooBar; + fn add(self, _rhs: Bar) -> FooBar { println!("> Foo.add(&Bar) was called"); @@ -21,7 +25,9 @@ impl Add for Foo { // Addition can be implemented in a non-commutative way // This block implements the operation: Bar + Foo = BarFoo -impl Add for Bar { +impl Add for Bar { + type Output = BarFoo; + fn add(self, _rhs: Foo) -> BarFoo { println!("> Bar.add(&Foo) was called"); From 7d295209c16d59d41d9ef65cdff398c07114e7a1 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 7 Jan 2015 21:11:23 -0500 Subject: [PATCH 0032/1122] Make deploy.sh script executable --- deploy.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 deploy.sh diff --git a/deploy.sh b/deploy.sh old mode 100644 new mode 100755 From 64294e3785c12396a3194e0b57ddbcaabd1446b7 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 8 Jan 2015 16:27:41 -0200 Subject: [PATCH 0033/1122] Fix bounds example according to latest nightly --- examples/bounds/bounds.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index 83a11a84d5..2c104e1100 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -1,4 +1,6 @@ -#[deriving(Show, Copy)] +use std::ops::{Add, Sub, Mul}; + +#[derive(Show, Copy)] struct Vec2 { x: T, y: T, @@ -6,8 +8,10 @@ struct Vec2 { // Apply bound to `T` at first instance of `T`. `T` // must implement the `Add` trait. -impl> Add, Vec2> +impl> Add> for Vec2 { + type Output = Vec2; + fn add(self, rhs: Vec2) -> Vec2 { Vec2 { // `x` and `y` are of type `T`, and implement the `add` method @@ -19,8 +23,10 @@ impl> Add, Vec2> } // Bound: `T` must implement the `Sub` trait -impl Sub, Vec2> for Vec2 - where T: Sub { +impl Sub> for Vec2 + where T: Sub { + type Output = Vec2; + fn sub(self, rhs: Vec2) -> Vec2 { Vec2 { x: self.x - rhs.x, @@ -30,8 +36,8 @@ impl Sub, Vec2> for Vec2 } // Bound: `T` must implement *both* the `Add` trait and the `Mul` trait -impl Vec2 - where T: Add + Mul { +impl Vec2 + where T: Add + Mul { fn dot(self, rhs: Vec2) -> T { (self.x * rhs.x) + (self.y * rhs.y) } From 2ae21ee49cc241031fc70eda5a998c9cc8d87b09 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 8 Jan 2015 15:04:33 -0500 Subject: [PATCH 0034/1122] Upgrade to HEAD Rust. It's unfortunate to lose all of the JSON stuff, but we can't use external crates with the current build system. --- Makefile | 2 +- examples/borrow/ref/ref.rs | 4 +- examples/box/box.rs | 2 +- examples/channels/channels.rs | 4 +- examples/clone/clone.rs | 14 +++--- examples/closures/closures.rs | 2 +- examples/fs/fs.rs | 20 ++++---- examples/generics/phantom/phantom.rs | 4 +- examples/generics/phantom/units/units.rs | 18 ++++--- examples/iter/iter.rs | 11 +++-- examples/lifetime/fn/fn.rs | 10 ++-- examples/match/guard/guard.rs | 2 +- examples/match/struct/struct.rs | 2 +- examples/ops/operator.rs | 8 ++-- examples/option/option.rs | 4 +- examples/result/result.rs | 8 ++-- examples/result/try/try.rs | 2 +- examples/staging/bench/bench.rs | 3 +- examples/staging/ffi/ffi.rs | 4 +- examples/staging/ffi/safe.rs | 4 +- examples/staging/fmt/show.rs | 4 +- .../hash/alt-key-types/alt-key-types.rs | 12 ++--- examples/staging/hash/hashset/hashset.rs | 8 ++-- examples/staging/json/decodable/decodable.rs | 48 ------------------- examples/staging/json/decodable/input.md | 13 ----- examples/staging/json/encodable/encodable.rs | 23 --------- examples/staging/json/encodable/input.md | 9 ---- examples/staging/json/input.md | 0 examples/staging/json/json-enum/input.md | 6 --- examples/staging/json/json-enum/json-enum.rs | 21 -------- examples/staging/macros/designators.rs | 2 - examples/staging/macros/dry.rs | 13 ++--- examples/staging/macros/overload.rs | 10 ++-- examples/staging/macros/repeat.rs | 2 - examples/staging/macros/simple.rs | 3 -- examples/staging/rand/deriving.rs | 8 ++-- examples/staging/simd/simd.rs | 2 +- examples/staging/simd/simd_add.rs | 13 +++-- examples/threads/threads.rs | 4 +- examples/timers/timers.rs | 11 +++-- examples/trait/deriving/deriving.rs | 6 +-- examples/tuples/tuples.rs | 10 ++-- 42 files changed, 119 insertions(+), 237 deletions(-) delete mode 100644 examples/staging/json/decodable/decodable.rs delete mode 100644 examples/staging/json/decodable/input.md delete mode 100644 examples/staging/json/encodable/encodable.rs delete mode 100644 examples/staging/json/encodable/input.md delete mode 100644 examples/staging/json/input.md delete mode 100644 examples/staging/json/json-enum/input.md delete mode 100644 examples/staging/json/json-enum/json-enum.rs diff --git a/Makefile b/Makefile index 9929d5c1c4..de2d762760 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -A experimental -RUSTC_NT = $(RUSTC) --no-trans --test $(QUIET) ${STRICT} +RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/borrow/borrow.rs \ examples/borrow/freeze/freeze.rs \ diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index 3cf7d0e7c4..0ae327c9dd 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,4 +1,4 @@ -#[deriving(Copy)] +#[derive(Copy)] struct Point { x: int, y: int } fn main() { @@ -36,5 +36,5 @@ fn main() { *i = 3; } - println!("tuple is {}", tuple); + println!("tuple is {:?}", tuple); } diff --git a/examples/box/box.rs b/examples/box/box.rs index 0f6111a042..3de5e5947e 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,7 +1,7 @@ use std::mem; #[allow(dead_code)] -#[deriving(Copy)] +#[derive(Copy)] struct Point { x: f64, y: f64, diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 5285afbb6a..c40423416e 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -23,7 +23,7 @@ fn main() { // Sending is a non-blocking operation, the thread will continue // immediately after sending its message println!("thread {} finished", id); - }).detach(); + }); } // Here, all the messages are collected @@ -35,5 +35,5 @@ fn main() { } // Show the order in which the messages were sent - println!("{}", ids); + println!("{:?}", ids); } diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index f5ffba8f3a..b2099e2dcf 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -1,9 +1,9 @@ // A unit struct without resources -#[deriving(Show, Copy)] +#[derive(Show, Copy)] struct Nil; // A tuple struct with resources that implements the `Clone` trait -#[deriving(Clone,Show)] +#[derive(Clone,Show)] struct Pair(Box, Box); fn main() { @@ -13,16 +13,16 @@ fn main() { let copied_nil = nil; // Both `Nil`s can be used independently - println!("original: {}", nil); - println!("copy: {}", copied_nil); + println!("original: {:?}", nil); + println!("copy: {:?}", copied_nil); // Instantiate a `Pair` let pair = Pair(box 1, box 2); - println!("original: {}", pair); + println!("original: {:?}", pair); // Copy `pair` into `moved_pair`, moves resources let moved_pair = pair; - println!("copy: {}", moved_pair); + println!("copy: {:?}", moved_pair); // Error! `pair` has lost it resources //println!("original: {}", pair); @@ -39,5 +39,5 @@ fn main() { // TODO ^ Try uncommenting this line // Clone can still be used - println!("clone: {}", cloned_pair); + println!("clone: {:?}", cloned_pair); } diff --git a/examples/closures/closures.rs b/examples/closures/closures.rs index 31c1b4758d..f98c8fe725 100644 --- a/examples/closures/closures.rs +++ b/examples/closures/closures.rs @@ -1,7 +1,7 @@ fn main() { let captured_value = 7u; - let closure = |argument| { + let closure = |&:argument| { println!("I captured this: {}", captured_value); println!("Argument passed was: {}", argument); diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 27daa1f6d0..61b213371a 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -25,44 +25,44 @@ fn main() { println!("`mkdir a`"); // Create a directory, returns `IoResult<()>` match fs::mkdir(&Path::new("a"), USER_RWX) { - Err(why) => println!("! {}", why.kind), + Err(why) => println!("! {:?}", why.kind), Ok(_) => {}, } println!("`echo hello > a/b.txt`"); // The previous match can be simplified using the `unwrap_or_else` method echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); println!("`mkdir -p a/c/d`"); // Recursively create a directory, returns `IoResult<()>` fs::mkdir_recursive(&Path::new("a/c/d"), USER_RWX).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); println!("`touch a/c/e.txt`"); touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); println!("`ln -s ../b.txt a/c/b.txt`"); // Create a symbolic link, returns `IoResult<()>` fs::symlink(&Path::new("../b.txt"), &Path::new("a/c/b.txt")).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); println!("`cat a/c/b.txt`"); match cat(&Path::new("a/c/b.txt")) { - Err(why) => println!("! {}", why.kind), + Err(why) => println!("! {:?}", why.kind), Ok(s) => println!("> {}", s), } println!("`ls a`"); // Read the contents of a directory, returns `IoResult>` match fs::readdir(&Path::new("a")) { - Err(why) => println!("! {}", why.kind), + Err(why) => println!("! {:?}", why.kind), Ok(paths) => for path in paths.iter() { println!("> {}", path.display()); }, @@ -72,7 +72,7 @@ fn main() { // Recursively walk over the contents of a directory, returns // `Directories`, which implements the `Iterator trait match fs::walk_dir(&Path::new("a")) { - Err(why) => println!("! {}", why.kind), + Err(why) => println!("! {:?}", why.kind), Ok(mut paths) => for path in paths { println!("> {}", path.display()); }, @@ -81,12 +81,12 @@ fn main() { println!("`rm a/c/e.txt`"); // Remove a file, returns `IoResult<()>` fs::unlink(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); println!("`rmdir a/c/d`"); // Remove an empty directory, returns `IoResult<()>` fs::rmdir(&Path::new("a/c/d")).unwrap_or_else(|why| { - println!("! {}", why.kind); + println!("! {:?}", why.kind); }); } diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs index 03b134ceda..a2f0f702c8 100644 --- a/examples/generics/phantom/phantom.rs +++ b/examples/generics/phantom/phantom.rs @@ -5,12 +5,12 @@ struct Tuple(A,); // This tuple is a phantom type. B is a hidden // parameter. Storage is allocated for generic type A // yet not for B. Therefore, B cannot be used in computations. -#[deriving(PartialEq)] // Allow equality test for this type +#[derive(PartialEq)] // Allow equality test for this type struct PhantomTuple(A,); // Similarly, a phantom type struct which is generic over A // with hidden parameter B -#[deriving(PartialEq)] // Allow equality test for this type +#[derive(PartialEq)] // Allow equality test for this type struct PhantomStruct { first: A } fn main() { diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index 798a12b5b9..d046dc1716 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -1,11 +1,13 @@ +use std::ops::Add; + // Null enumerations to define unit types -#[deriving(Show, Copy)] +#[derive(Show, Copy)] enum Inch {} -#[deriving(Show, Copy)] +#[derive(Show, Copy)] enum Mm {} // Length is phantom type with hidden parameter `Unit` -#[deriving(Show, Copy)] +#[derive(Show, Copy)] struct Length(T,); // `impl X for Y {}` reads "implement `X` Trait for Type `Y`" @@ -17,8 +19,10 @@ struct Length(T,); // This means that this `impl` defines `Add` only for `T` when // two `T's` can be added together and the result is of // Type `T`: (`T: Add`) -impl + Copy> Add, - Length> for Length { +impl + Copy> Add> + for Length { + type Output = Length; + fn add(self, r: Length) -> Length { let Length(ref left) = self; let Length(ref right) = r; @@ -37,8 +41,8 @@ fn main() { let two_meters = one_meter + one_meter; // Addition works - println!("one foot + one_foot = {}", two_feet); - println!("one meter + one_meter = {}", two_meters); + println!("one foot + one_foot = {:?}", two_feet); + println!("one meter + one_meter = {:?}", two_meters); // Nonsensical operations fail as they should // Error: type mismatch diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index 8c8dbeff71..ce5ace8a17 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -6,7 +6,8 @@ struct Fibonacci { } // Implement 'Iterator' for 'Fibonacci' -impl Iterator for Fibonacci { +impl Iterator for Fibonacci { + type Item = uint; // The 'Iterator' trait only requires the 'next' method to be defined. The // return type is 'Option', 'None' is returned when the 'Iterator' is // over, otherwise the next value is returned wrapped in 'Some' @@ -29,10 +30,10 @@ fn main() { let mut sequence = range(0u, 3); println!("Four consecutive `next` calls on range(0, 3)"); - println!("> {}", sequence.next()); - println!("> {}", sequence.next()); - println!("> {}", sequence.next()); - println!("> {}", sequence.next()); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); // The for construct will iterate an 'Iterator' until it returns 'None'. // Every 'Some' value is unwrapped and bound to a variable. diff --git a/examples/lifetime/fn/fn.rs b/examples/lifetime/fn/fn.rs index ff462e64fa..cb0781b233 100644 --- a/examples/lifetime/fn/fn.rs +++ b/examples/lifetime/fn/fn.rs @@ -1,4 +1,4 @@ -#[deriving(Show)] +#[derive(Show)] struct Triplet { one: int, two: int, @@ -11,7 +11,7 @@ impl Triplet { fn mut_one(&mut self) -> &mut int { &mut self.one } - + // Second attempt: We explicitly annotate the lifetimes on all the // references // Error! The compiler doesn't know what is the relationship between the @@ -38,13 +38,13 @@ impl Triplet { fn main() { let mut triplet = Triplet { one: 1, two: 2, three: 3 }; - println!("Before: {}", triplet); + println!("Before: {:?}", triplet); *triplet.mut_one() = 0; - println!("After: {}", triplet); + println!("After: {:?}", triplet); // Use mutable reference to modify the original struct *triplet.mut_three() = 0; - println!("After: {}", triplet); + println!("After: {:?}", triplet); } diff --git a/examples/match/guard/guard.rs b/examples/match/guard/guard.rs index dd8d184e9e..1e42350706 100644 --- a/examples/match/guard/guard.rs +++ b/examples/match/guard/guard.rs @@ -2,7 +2,7 @@ fn main() { let pair = (2i, -2); // TODO ^ Try different values for `pair` - println!("Tell me about {}", pair); + println!("Tell me about {:?}", pair); // Match can be used to destructure a tuple match pair { // Destructure the tuple diff --git a/examples/match/struct/struct.rs b/examples/match/struct/struct.rs index 7e1d5d3194..afa2ed8d00 100644 --- a/examples/match/struct/struct.rs +++ b/examples/match/struct/struct.rs @@ -11,7 +11,7 @@ fn main() { // the order is not important let Foo { y: i, x: j } = foo; - println!("i = {}, j = {}", i, j); + println!("i = {:?}, j = {:?}", i, j); // and you can also ignore some variables: let Foo { y, .. } = foo; diff --git a/examples/ops/operator.rs b/examples/ops/operator.rs index df6d47f20e..c50fcb0be1 100644 --- a/examples/ops/operator.rs +++ b/examples/ops/operator.rs @@ -15,7 +15,7 @@ struct BarFoo; // This block implements the operation: Foo + Bar = FooBar impl Add for Foo { type Output = FooBar; - + fn add(self, _rhs: Bar) -> FooBar { println!("> Foo.add(Bar) was called"); @@ -27,7 +27,7 @@ impl Add for Foo { // This block implements the operation: Bar + Foo = BarFoo impl Add for Bar { type Output = BarFoo; - + fn add(self, _rhs: Foo) -> BarFoo { println!("> Bar.add(Foo) was called"); @@ -36,6 +36,6 @@ impl Add for Bar { } fn main() { - println!("Foo + Bar = {}", Foo + Bar); - println!("Bar + Foo = {}", Bar + Foo); + println!("Foo + Bar = {:?}", Foo + Bar); + println!("Bar + Foo = {:?}", Bar + Foo); } diff --git a/examples/option/option.rs b/examples/option/option.rs index fd89338c6b..d76f9e2492 100644 --- a/examples/option/option.rs +++ b/examples/option/option.rs @@ -32,6 +32,6 @@ fn main() { // The `unwrap` method will extract the value wrapped in a `Some` variant, // or will `panic!` if called on a `None` variant - println!("{} unwraps to {}", optional_float, optional_float.unwrap()); - println!("{} unwraps to {}", none, none.unwrap()); + println!("{:?} unwraps to {:?}", optional_float, optional_float.unwrap()); + println!("{:?} unwraps to {:?}", none, none.unwrap()); } diff --git a/examples/result/result.rs b/examples/result/result.rs index 53ccd532e4..1334ae3ab0 100644 --- a/examples/result/result.rs +++ b/examples/result/result.rs @@ -2,7 +2,7 @@ mod checked { // For .ln() and .sqrt() use std::num::Float; // Mathematical "errors" we want to catch - #[deriving(Show)] + #[derive(Show)] pub enum MathError { DivisionByZero, NegativeLogarithm, @@ -43,11 +43,11 @@ mod checked { fn op(x: f64, y: f64) -> f64 { // This is a three level match pyramid! match checked::div(x, y) { - Err(why) => panic!("{}", why), + Err(why) => panic!("{:?}", why), Ok(ratio) => match checked::ln(ratio) { - Err(why) => panic!("{}", why), + Err(why) => panic!("{:?}", why), Ok(ln) => match checked::sqrt(ln) { - Err(why) => panic!("{}", why), + Err(why) => panic!("{:?}", why), Ok(sqrt) => sqrt, }, }, diff --git a/examples/result/try/try.rs b/examples/result/try/try.rs index d2259f0dd1..dee7d14028 100644 --- a/examples/result/try/try.rs +++ b/examples/result/try/try.rs @@ -2,7 +2,7 @@ mod checked { // For .sqrt() and .ln() use std::num::Float; - #[deriving(Show)] + #[derive(Show)] enum MathError { DivisionByZero, NegativeLogarithm, diff --git a/examples/staging/bench/bench.rs b/examples/staging/bench/bench.rs index dbcd4fc78d..49fc3f4cbc 100644 --- a/examples/staging/bench/bench.rs +++ b/examples/staging/bench/bench.rs @@ -21,7 +21,8 @@ struct Fibonacci { next: uint, } -impl Iterator for Fibonacci { +impl Iterator for Fibonacci { + type Item = uint; fn next(&mut self) -> Option { let new_next = self.curr + self.next; let new_curr = replace(&mut self.next, new_next); diff --git a/examples/staging/ffi/ffi.rs b/examples/staging/ffi/ffi.rs index 7f0aa11ff9..767813ead3 100644 --- a/examples/staging/ffi/ffi.rs +++ b/examples/staging/ffi/ffi.rs @@ -17,12 +17,12 @@ fn main() { csqrtf(z) }; - println!("the square root of {} is {}", z, z_sqrt); + println!("the square root of {:?} is {:?}", z, z_sqrt); } // Minimal implementation of single precision complex numbers #[repr(C)] -#[deriving(Copy)] +#[derive(Copy)] struct Complex { re: f32, im: f32, diff --git a/examples/staging/ffi/safe.rs b/examples/staging/ffi/safe.rs index f089733209..02005d6cd6 100644 --- a/examples/staging/ffi/safe.rs +++ b/examples/staging/ffi/safe.rs @@ -14,12 +14,12 @@ fn main() { // z = 0 + 1i let z = Complex { re: 0., im: 1. }; - println!("cos({}) = {}", z, cos(z)); + println!("cos({:?}) = {:?}", z, cos(z)); } // Minimal implementation of single precision complex numbers #[repr(C)] -#[deriving(Copy)] +#[derive(Copy)] struct Complex { re: f32, im: f32, diff --git a/examples/staging/fmt/show.rs b/examples/staging/fmt/show.rs index 4dee713351..da6d1cf241 100644 --- a/examples/staging/fmt/show.rs +++ b/examples/staging/fmt/show.rs @@ -1,4 +1,4 @@ -use std::fmt::{mod,Formatter,Show}; +use std::fmt::{self, Formatter, Show}; // For .abs() use std::num::Float; @@ -29,7 +29,7 @@ fn main() { City { name: "Oslo", lat: 59.95, lon: 10.75 }, City { name: "Vancouver", lat: 49.25, lon: -123.1 }, ].iter() { - println!("{}", city); + println!("{:?}", city); } } diff --git a/examples/staging/hash/alt-key-types/alt-key-types.rs b/examples/staging/hash/alt-key-types/alt-key-types.rs index fb5fdce145..19103b4ba1 100644 --- a/examples/staging/hash/alt-key-types/alt-key-types.rs +++ b/examples/staging/hash/alt-key-types/alt-key-types.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; // Eq requires that you derive PartialEq on the type. -#[deriving(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] struct Account<'a>{ username: &'a str, password: &'a str, @@ -14,7 +14,7 @@ struct AccountInfo<'a>{ type Accounts<'a> = HashMap, AccountInfo<'a>>; -fn try_logon<'a>(accounts: &Accounts<'a>, +fn try_logon<'a>(accounts: &Accounts<'a>, username: &'a str, password: &'a str){ println!("Username: {}", username); println!("Password: {}", password); @@ -39,18 +39,18 @@ fn main(){ let mut accounts: Accounts = HashMap::new(); let account = Account { - username: "j.everyman", - password: "password123", + username: "j.everyman", + password: "password123", }; let account_info = AccountInfo { name: "John Everyman", email: "j.everyman@email.com", }; - + accounts.insert(account, account_info); try_logon(&accounts, "j.everyman", "psasword123"); - + try_logon(&accounts, "j.everyman", "password123"); } diff --git a/examples/staging/hash/hashset/hashset.rs b/examples/staging/hash/hashset/hashset.rs index 3c7e82eefa..904189b4f6 100644 --- a/examples/staging/hash/hashset/hashset.rs +++ b/examples/staging/hash/hashset/hashset.rs @@ -15,10 +15,10 @@ fn main() { b.insert(5); // If a collection's element type implements `Show`, - // then the collection implements `Show`. + // then the collection implements `Show`. // It usually prints its elements in the format `[elem1, elem2, ...]` - println!("A: {}", a); - println!("B: {}", b); + println!("A: {:?}", a); + println!("B: {:?}", b); // Print [1, 2, 3, 4, 5] in arbitrary order println!("Union: {}", a.union(&b).collect::>()); @@ -30,7 +30,7 @@ fn main() { println!("Intersection: {}", a.intersection(&b).collect::>()); // Print [1, 5] - println!("Symmetric Difference: {}", + println!("Symmetric Difference: {}", a.symmetric_difference(&b).collect::>()); } diff --git a/examples/staging/json/decodable/decodable.rs b/examples/staging/json/decodable/decodable.rs deleted file mode 100644 index d4f6cbef9a..0000000000 --- a/examples/staging/json/decodable/decodable.rs +++ /dev/null @@ -1,48 +0,0 @@ -extern crate serialize; - -use serialize::{json, Decodable}; - -#[deriving(Decodable)] -struct City { - name: String, - // Latitude - lat: f32, - // Longitude - lon: f32, -} - -fn main() { - for &json_str in [ - r#"{"name": "Cape Town", "lat": -33.925, "lon": 18.424}"#, - - // Any extra fields will be ignored: - r#"{"name": "Tokyo", "country": "Japan", "lat": -33.925, - "lon": 18.424}"#, - - // However, a missing field will cause an error: - r#"{"lat": -33.86, "lon": 151.209}"#, - // FIXME ^ fill in the missing field: "name": "Sydney" - ].iter() { - let json_object = match json::from_str(json_str) { - Ok(json) => json, - Err(err) => { - println!("json::from_str: {}", err); - continue; - }, - }; - - // A `Decoder` object is created based on the `json_object` - // using which a `City` struct can be decoded: - let mut decoder = json::Decoder::new(json_object); - let city: City = match Decodable::decode(&mut decoder) { - Ok(city) => city, - Err(err) => { - println!("Decodable::decode: {}", err); - continue; - }, - }; - - println!("City: {} ({:.2}° N, {:.2}° E)", - city.name, city.lat, city.lon); - } -} diff --git a/examples/staging/json/decodable/input.md b/examples/staging/json/decodable/input.md deleted file mode 100644 index 80f895e5e5..0000000000 --- a/examples/staging/json/decodable/input.md +++ /dev/null @@ -1,13 +0,0 @@ -`serialize::Decodable` is a trait implemented for types to make them decodable -by the `serialize` module. - -To deserialize a type from a `Json` enum, a `serialize::json::Decoder` is first -created for this `Json`. It can then be used to decode data into `Decodable`s. - -To make this task easier, `Decodable` can be automatically derived for a struct -using `#[deriving(Decodable)]`. This creates a default implementation -in which key-value pairs of a JSON object are mapped to -fields of a `struct`. The keys are expected to have exactly the same -names as the `struct` fields, including case. - -{decodable.play} diff --git a/examples/staging/json/encodable/encodable.rs b/examples/staging/json/encodable/encodable.rs deleted file mode 100644 index c6be8b8245..0000000000 --- a/examples/staging/json/encodable/encodable.rs +++ /dev/null @@ -1,23 +0,0 @@ -extern crate serialize; - -use serialize::{json, Encodable}; - -#[deriving(Encodable)] -struct City { - name: &'static str, - // Latitude - lat: f32, - // Longitude - lon: f32, -} - -fn main() { - for city in [ - City { name: "São Paulo", lat: -23.55, lon: -46.633333 }, - City { name: "Lima", lat: -12.043333, lon: -77.028333 }, - City { name: "Santiago", lat: -33.45, lon: -70.666667 }, - ].iter() { - // `encode` encodes an `Encodable` implementor into a `String` - println!("{}", json::encode(city)); - } -} diff --git a/examples/staging/json/encodable/input.md b/examples/staging/json/encodable/input.md deleted file mode 100644 index 18371ed423..0000000000 --- a/examples/staging/json/encodable/input.md +++ /dev/null @@ -1,9 +0,0 @@ -`serialize::Encodable` is a trait implemented for types to make them encodable -by the `serialize` module. - -`Encodable` types can be serialized into JSON using `json::encode`. - -Just like `Decodable`, `Encodable` can be automatically derived for a struct -using `#[deriving(Encodable)]`. - -{encodable.play} diff --git a/examples/staging/json/input.md b/examples/staging/json/input.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/staging/json/json-enum/input.md b/examples/staging/json/json-enum/input.md deleted file mode 100644 index 1e9fd16c14..0000000000 --- a/examples/staging/json/json-enum/input.md +++ /dev/null @@ -1,6 +0,0 @@ -`serialize::json::Json` is an enum capable of containing all of the -JSON value types. It is Rust's way of representing JSON documents. - -`Json` can be decoded from a JSON string using `seralize::json::from_str`: - -{json-enum.play} diff --git a/examples/staging/json/json-enum/json-enum.rs b/examples/staging/json/json-enum/json-enum.rs deleted file mode 100644 index 811dd5c541..0000000000 --- a/examples/staging/json/json-enum/json-enum.rs +++ /dev/null @@ -1,21 +0,0 @@ -extern crate serialize; - -use serialize::json; - -fn main() { - for &json_str in [ - // Valid JSON - r#"{"name": "London", "lat": 51.507222, "lon": -0.1275}"#, - - // Not a valid JSON, will produce an error - r#"{"name": "Prague" "lat": 50.082542, "lon": 14.425992}"#, - // FIXME ^ a comma is missing here - ].iter() { - // `from_str` decodes JSON from a string and returns a `Result` - // containing either a `Json` enum or an error - match json::from_str(json_str) { - Ok(json) => println!("json::from_str(): {}", json), - Err(err) => println!("json::from_str(): {}", err), - }; - } -} diff --git a/examples/staging/macros/designators.rs b/examples/staging/macros/designators.rs index a8c1928ca7..d93a2cf905 100644 --- a/examples/staging/macros/designators.rs +++ b/examples/staging/macros/designators.rs @@ -1,5 +1,3 @@ -#![feature(macro_rules)] - macro_rules! create_function { // this macro takes an argument of "type" `ident` // the `ident` designator is used for variable/function names diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry.rs index 8ac526c9c5..d68438148a 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry.rs @@ -1,10 +1,10 @@ -#![feature(macro_rules)] use std::iter; +use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { ($a:ident, $b: ident, $func:ident, $op:tt) => { assert!($a.len() == $b.len(), - "{}: dimension mismatch: {} {} {}", + "{}: dimension mismatch: {:?} {} {:?}", stringify!($func), ($a.len(),), stringify!($op), @@ -14,7 +14,7 @@ macro_rules! assert_equal_len { macro_rules! op { ($func:ident, $bound:ident, $op:tt, $method:ident) => { - fn $func + Copy>(xs: &mut Vec, ys: &Vec) { + fn $func + Copy>(xs: &mut Vec, ys: &Vec) { assert_equal_len!(xs, ys, $func, $op); for (x, y) in xs.iter_mut().zip(ys.iter()) { @@ -39,14 +39,15 @@ fn main() { } mod test { + use std::iter; macro_rules! test { ($func: ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { for size in range(0u, 10) { - let mut x = Vec::from_elem(size, $x); - let y = Vec::from_elem(size, $y); - let z = Vec::from_elem(size, $z); + let mut x: Vec<_> = iter::repeat(size).take($x).collect(); + let y: Vec<_> = iter::repeat(size).take($y).collect(); + let z: Vec<_> = iter::repeat(size).take($z).collect(); super::$func(&mut x, &y); diff --git a/examples/staging/macros/overload.rs b/examples/staging/macros/overload.rs index e1e04b20fe..8005bfbbad 100644 --- a/examples/staging/macros/overload.rs +++ b/examples/staging/macros/overload.rs @@ -1,17 +1,15 @@ -#![feature(macro_rules)] - // macro_rules! is similar to a match block macro_rules! test { // the arguments don't need to be separated by a comma // any template can be used - ($left:expr and $right:expr) => { + ($left:expr; and $right:expr) => { println!("{} and {} is {}", stringify!($left), stringify!($right), $left && $right) }; // ^ each arm must be ended with a semicolon - ($left:expr or $right:expr) => { + ($left:expr; or $right:expr) => { println!("{} or {} is {}", stringify!($left), stringify!($right), @@ -20,6 +18,6 @@ macro_rules! test { } fn main() { - test!(1i + 1 == 2i and 2i * 2 == 4i); - test!(true or false); + test!(1i + 1 == 2i; and 2i * 2 == 4i); + test!(true; or false); } diff --git a/examples/staging/macros/repeat.rs b/examples/staging/macros/repeat.rs index dbe6258b2e..9dc603ac80 100644 --- a/examples/staging/macros/repeat.rs +++ b/examples/staging/macros/repeat.rs @@ -1,5 +1,3 @@ -#![feature(macro_rules)] - // min! will calculate the minimum of any number of arguments macro_rules! min { // base case diff --git a/examples/staging/macros/simple.rs b/examples/staging/macros/simple.rs index 648bc07295..a5731e454b 100644 --- a/examples/staging/macros/simple.rs +++ b/examples/staging/macros/simple.rs @@ -1,6 +1,3 @@ -// macros are behind a feature gate -#![feature(macro_rules)] - // This is the simplest macro, `say_hello` is the name of the macro macro_rules! say_hello { // `()` indicates that the macro takes no argument diff --git a/examples/staging/rand/deriving.rs b/examples/staging/rand/deriving.rs index 36358f46bf..ab73f6e2c5 100644 --- a/examples/staging/rand/deriving.rs +++ b/examples/staging/rand/deriving.rs @@ -1,13 +1,13 @@ use std::rand; use std::rand::Rng; -#[deriving(Rand,Show)] +#[derive(Rand,Show)] struct Point { x: f64, y: f64, } -#[deriving(Rand,Show)] +#[derive(Rand,Show)] struct Rectangle { p1: Point, p2: Point, @@ -16,6 +16,6 @@ struct Rectangle { fn main() { let mut rng = rand::thread_rng(); - println!("random point\n{}", rng.gen::()); - println!("random rectangle\n{}", rng.gen::()); + println!("random point\n{:?}", rng.gen::()); + println!("random rectangle\n{:?}", rng.gen::()); } diff --git a/examples/staging/simd/simd.rs b/examples/staging/simd/simd.rs index e702374f13..4f7055eccb 100644 --- a/examples/staging/simd/simd.rs +++ b/examples/staging/simd/simd.rs @@ -11,5 +11,5 @@ fn main() { // like any struct, the simd vector can be destructured using `let` let f32x4(a, b, c, d) = z; - println!("{}", (a, b, c, d)); + println!("{:?}", (a, b, c, d)); } diff --git a/examples/staging/simd/simd_add.rs b/examples/staging/simd/simd_add.rs index 766bf7a326..f29f3fc194 100644 --- a/examples/staging/simd/simd_add.rs +++ b/examples/staging/simd/simd_add.rs @@ -1,11 +1,9 @@ -#![feature(macro_rules)] - use std::simd::f32x4; macro_rules! assert_equal_len { ($a:ident, $b: ident) => { assert!($a.len() == $b.len(), - "add_assign: dimension mismatch: {} += {}", + "add_assign: dimension mismatch: {:?} += {:?}", ($a.len(),), ($b.len(),)); } @@ -55,14 +53,19 @@ fn simd_add_assign(xs: &mut Vec, ys: &Vec) { mod bench { extern crate test; use self::test::Bencher; + use std::iter; static BENCH_SIZE: uint = 10_000; macro_rules! bench { ($name:ident, $func:ident) => { #[bench] fn $name(b: &mut Bencher) { - let mut x = Vec::from_elem(BENCH_SIZE, 1.0f32); - let y = Vec::from_elem(BENCH_SIZE, 0.1f32); + let mut x: Vec<_> = iter::repeat(1.0f32) + .take(BENCH_SIZE) + .collect(); + let y: Vec<_> = iter::repeat(1.0f32) + .take(BENCH_SIZE) + .collect(); b.iter(|| { super::$func(&mut x, &y); diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index 4ba8e25e1b..7e7057e7e7 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -6,8 +6,8 @@ static NTHREADS: int = 10; fn main() { for i in range(0, NTHREADS) { // Spin up another thread - let _ = Thread::spawn(move || { + let _ = Thread::scoped(move || { println!("this is thread number {}", i) - }).join(); + }); } } diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 4fbc9ac81c..0a07ce7afc 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -2,6 +2,7 @@ use std::io::Timer; use std::io::timer; use std::time::duration::Duration; use std::iter; +use std::sync::mpsc; fn main() { let interval = Duration::milliseconds(1000); @@ -10,12 +11,12 @@ fn main() { // Create a one-shot notification // (superfluous type annotation) - let oneshot: Receiver<()> = timer.oneshot(interval); + let oneshot: mpsc::Receiver<()> = timer.oneshot(interval); println!("Wait {} ms...", interval.num_milliseconds()); // Block the task until notification arrives - oneshot.recv(); + let _ = oneshot.recv(); println!("Done"); @@ -28,15 +29,15 @@ fn main() { // The same timer can be used to generate periodic notifications // (superfluous type annotation) - let metronome: Receiver<()> = timer.periodic(interval); + let metronome: mpsc::Receiver<()> = timer.periodic(interval); println!("Countdown"); for i in iter::range_step(5i, 0, -1) { // This loop will run once every second - metronome.recv(); + let _ = metronome.recv(); println!("{}", i); } - metronome.recv(); + let _ = metronome.recv(); println!("Ignition!"); } diff --git a/examples/trait/deriving/deriving.rs b/examples/trait/deriving/deriving.rs index 7b2bd9abf9..a8b27bf950 100644 --- a/examples/trait/deriving/deriving.rs +++ b/examples/trait/deriving/deriving.rs @@ -1,9 +1,9 @@ // A tuple struct that can be compared -#[deriving(PartialEq, PartialOrd)] +#[derive(PartialEq, PartialOrd)] struct Centimeters(f64); // A tuple struct that can be printed -#[deriving(Show)] +#[derive(Show)] struct Inches(int); impl Inches { @@ -32,7 +32,7 @@ fn main() { let foot = Inches(12); - println!("One foot === {}", foot); + println!("One foot === {:?}", foot); let meter = Centimeters(100.0); diff --git a/examples/tuples/tuples.rs b/examples/tuples/tuples.rs index 21a2d0f017..fe8322bb66 100644 --- a/examples/tuples/tuples.rs +++ b/examples/tuples/tuples.rs @@ -21,15 +21,15 @@ fn main() { let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); // Tuples are printable - println!("tuple of tuples: {}", tuple_of_tuples); + println!("tuple of tuples: {:?}", tuple_of_tuples); let pair = (1, true); - println!("pair is {}", pair); + println!("pair is {:?}", pair); - println!("the reversed pair is {}", reverse(pair)); + println!("the reversed pair is {:?}", reverse(pair)); // To create one element tuples, the comma is required to tell them apart // from a literal surrounded by parentheses - println!("one element tuple: {}", (5u,)); - println!("just an integer: {}", (5u)); + println!("one element tuple: {:?}", (5u,)); + println!("just an integer: {:?}", (5u)); } From fa59f4b3027e6993d0ec9051a7901686ed7cd426 Mon Sep 17 00:00:00 2001 From: Steven Crockett Date: Fri, 9 Jan 2015 15:29:15 +0000 Subject: [PATCH 0035/1122] array: Update documentation to new fixed-length array syntax. --- examples/array/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/array/input.md b/examples/array/input.md index e60e8e5fc5..45c14702b4 100644 --- a/examples/array/input.md +++ b/examples/array/input.md @@ -1,6 +1,6 @@ An array is a collection of objects of the same type `T`, stored in contiguous memory. Arrays are created using brackets `[]`, and their size, which is known -at compile time, is part of their type signature `[T, ..size]`. +at compile time, is part of their type signature `[T; size]`. Slices are similar to arrays, but their size is not known at compile time. Instead, a slice is two-word object, the first word is a pointer to the data, From cfb95581b6ada90ba925c5b51c66a27beb69ef7f Mon Sep 17 00:00:00 2001 From: Sanjiv Jha Date: Sat, 10 Jan 2015 01:44:13 +0530 Subject: [PATCH 0036/1122] fix typo mistake !dash to !bash --- setup-stage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup-stage.sh b/setup-stage.sh index e5e46bb9f0..484ae186a9 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -1,4 +1,4 @@ -#!/bin/dash +#!/bin/bash ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min-noconflict' ace_local_folder='node_modules/gitbook-plugin-rust-playpen/book/ace' From 5a45c0d896a70fd4eb79da2bb5c0a46c0d7cad65 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Fri, 9 Jan 2015 22:09:17 -0800 Subject: [PATCH 0037/1122] Update to latest rustc (int -> i32) Also add #[feature(box_syntax)] for places where it is necessary. Rename `-A experimental` to `-A unstable` --- .gitignore | 1 + Makefile | 2 +- examples/array/array.rs | 6 +++--- examples/borrow/alias/alias.rs | 2 +- examples/borrow/ref/ref.rs | 6 ++++-- examples/box/box.rs | 2 ++ examples/channels/channels.rs | 4 ++-- examples/clone/clone.rs | 4 +++- examples/closures/closures.rs | 2 +- examples/enum/c-like/c-like.rs | 4 ++-- examples/enum/enum.rs | 8 +++++--- examples/expression/expression.rs | 8 ++++---- examples/fn/fn.rs | 6 +++--- examples/for/for.rs | 2 +- examples/generics/generics.rs | 4 ++-- examples/hof/hof.rs | 8 ++++---- examples/if-else/if-else.rs | 2 +- examples/iter/iter.rs | 16 ++++++++-------- examples/lifetime/explicit/explicit.rs | 2 +- examples/lifetime/fn/fn.rs | 12 ++++++------ examples/lifetime/struct/struct.rs | 4 ++-- examples/literals/literals.rs | 18 +++++++++--------- examples/loop/loop.rs | 2 +- examples/match/guard/guard.rs | 2 +- examples/match/match.rs | 4 ++-- examples/match/struct/struct.rs | 2 +- examples/methods/methods.rs | 4 +++- examples/move/move.rs | 8 +++++--- examples/move/mut/mut.rs | 4 +++- examples/option/option.rs | 8 ++++---- examples/panic/panic.rs | 6 ++++-- examples/raii/raii.rs | 10 ++++++---- examples/staging/arg/args.rs | 2 +- examples/staging/arg/getopts/testopt.rs | 2 +- examples/staging/arg/matching/match_args.rs | 6 +++--- examples/staging/bench/bench.rs | 16 ++++++++-------- examples/staging/hash/hashset/hashset.rs | 14 +++++++------- examples/staging/macros/designators.rs | 4 ++-- examples/staging/macros/dry.rs | 8 ++++---- examples/staging/macros/overload.rs | 2 +- examples/staging/macros/repeat.rs | 6 +++--- examples/staging/rand/distributions.rs | 4 ++-- examples/staging/rand/gen.rs | 8 ++++---- examples/staging/simd/simd_add.rs | 4 ++-- examples/staging/test/fail.rs | 2 +- examples/structs/structs.rs | 4 ++-- examples/threads/threads.rs | 2 +- examples/timers/timers.rs | 2 +- examples/trait/deriving/deriving.rs | 4 ++-- examples/tuples/tuples.rs | 6 +++--- examples/type/inference/inference.rs | 2 +- examples/type/literals/literals.rs | 2 +- examples/variables/variables.rs | 12 ++++++------ examples/while/while.rs | 2 +- 54 files changed, 153 insertions(+), 134 deletions(-) diff --git a/.gitignore b/.gitignore index c29ce06384..20620ac0df 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ bin/* stage/* node_modules/* !node_modules/gitbook-plugin-rust-playpen +node_modules/gitbook-plugin-rust-playpen/book/ace diff --git a/Makefile b/Makefile index de2d762760..fc083586f9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated -QUIET = -A unused-variables -A dead-code -A unused-assignments -A experimental +QUIET = -A unused-variables -A dead-code -A unused-assignments -A unstable RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/borrow/borrow.rs \ diff --git a/examples/array/array.rs b/examples/array/array.rs index bf55fc267b..01fb6ce1ca 100644 --- a/examples/array/array.rs +++ b/examples/array/array.rs @@ -1,17 +1,17 @@ use std::mem; // This function borrows a slice -fn analyze_slice(slice: &[int]) { +fn analyze_slice(slice: &[i32]) { println!("first element of the slice: {}", slice[0]); println!("the slice has {} elements", slice.len()); } fn main() { // Fixed-size array (type signature is superfluous) - let xs: [int; 5] = [1, 2, 3, 4, 5]; + let xs: [i32; 5] = [1, 2, 3, 4, 5]; // All elements can be initialized to the same value - let ys: [int; 500] = [0; 500]; + let ys: [i32; 500] = [0; 500]; // Indexing starts at 0 println!("first element of the array: {}", xs[0]); diff --git a/examples/borrow/alias/alias.rs b/examples/borrow/alias/alias.rs index a3510fa573..70919bd7f9 100644 --- a/examples/borrow/alias/alias.rs +++ b/examples/borrow/alias/alias.rs @@ -1,4 +1,4 @@ -struct Point { x: int, y: int, z: int } +struct Point { x: i32, y: i32, z: i32 } fn main() { let mut point = Point { x: 0, y: 0, z: 0 }; diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index 0ae327c9dd..9f84dff746 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,5 +1,7 @@ +#![feature(box_syntax)] + #[derive(Copy)] -struct Point { x: int, y: int } +struct Point { x: i32, y: i32 } fn main() { let point = Point { x: 0, y: 0 }; @@ -26,7 +28,7 @@ fn main() { println!("point is ({}, {})", point.x, point.y); println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); - let mut tuple = (box 5u, 3u); + let mut tuple = (box 5u32, 3u32); { // `ref` can also be paired with `box` to take a mutable reference to diff --git a/examples/box/box.rs b/examples/box/box.rs index 3de5e5947e..12b4b1293f 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,3 +1,5 @@ +#![feature(box_syntax)] + use std::mem; #[allow(dead_code)] diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index c40423416e..4a78e2f5a7 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -2,13 +2,13 @@ use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; use std::thread::Thread; -static NTHREADS: uint = 3; +static NTHREADS: usize = 3; fn main() { // Channels have two endpoints: the `Sender` and the `Receiver`, // where `T` is the type of the message to be transfer // (type annotation is superfluous) - let (tx, rx): (Sender, Receiver) = mpsc::channel(); + let (tx, rx): (Sender, Receiver) = mpsc::channel(); for id in range(0, NTHREADS) { // The sender endpoint can be copied diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index b2099e2dcf..19997be5a4 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -1,10 +1,12 @@ +#![feature(box_syntax)] + // A unit struct without resources #[derive(Show, Copy)] struct Nil; // A tuple struct with resources that implements the `Clone` trait #[derive(Clone,Show)] -struct Pair(Box, Box); +struct Pair(Box, Box); fn main() { // Instantiate `Nil` diff --git a/examples/closures/closures.rs b/examples/closures/closures.rs index f98c8fe725..11129205ce 100644 --- a/examples/closures/closures.rs +++ b/examples/closures/closures.rs @@ -1,5 +1,5 @@ fn main() { - let captured_value = 7u; + let captured_value = 7u32; let closure = |&:argument| { println!("I captured this: {}", captured_value); diff --git a/examples/enum/c-like/c-like.rs b/examples/enum/c-like/c-like.rs index cff6396cf9..ec7afa53c2 100644 --- a/examples/enum/c-like/c-like.rs +++ b/examples/enum/c-like/c-like.rs @@ -48,6 +48,6 @@ fn main() { today.mood(); // enums can be casted into integers - println!("roses are #{:06x}", Color::Red as int); - println!("violets are #{:06x}", Color::Blue as int); + println!("roses are #{:06x}", Color::Red as i32); + println!("violets are #{:06x}", Color::Blue as i32); } diff --git a/examples/enum/enum.rs b/examples/enum/enum.rs index a2b7f8b06e..d6955d1140 100644 --- a/examples/enum/enum.rs +++ b/examples/enum/enum.rs @@ -1,10 +1,12 @@ +#![feature(box_syntax)] + // Allow Cons and Nil to be referred to without namespacing use List::{Cons, Nil}; // A linked list node, which can take on any of these two variants enum List { // Cons: Tuple struct that wraps an element and a pointer to the next node - Cons(uint, Box), + Cons(u32, Box), // Nil: A node that signifies the end of the linked list Nil, } @@ -18,13 +20,13 @@ impl List { } // Consume a list, and return the same list with a new element at its front - fn prepend(self, elem: uint) -> List { + fn prepend(self, elem: u32) -> List { // `Cons` also has type List Cons(elem, box self) } // Return the length of the list - fn len(&self) -> uint { + fn len(&self) -> u32 { // `self` has to be matched, because the behavior of this method // depends on the variant of `self` // `self` has type `&List`, and `*self` has type `List`, matching on a diff --git a/examples/expression/expression.rs b/examples/expression/expression.rs index e06489ad27..09a7ff06d5 100644 --- a/examples/expression/expression.rs +++ b/examples/expression/expression.rs @@ -1,5 +1,5 @@ fn main() { - let x = 5u; + let x = 5u32; let y = { let x_squared = x * x; @@ -14,7 +14,7 @@ fn main() { 2 * x; }; - println!("x is {}", x); - println!("y is {}", y); - println!("z is {}", z); + println!("x is {:?}", x); + println!("y is {:?}", y); + println!("z is {:?}", z); } diff --git a/examples/fn/fn.rs b/examples/fn/fn.rs index 01df12493b..ff35d81e52 100644 --- a/examples/fn/fn.rs +++ b/examples/fn/fn.rs @@ -5,7 +5,7 @@ fn main() { } // Function that returns a boolean value -fn is_divisible_by(lhs: uint, rhs: uint) -> bool { +fn is_divisible_by(lhs: u32, rhs: u32) -> bool { // Corner case, early return if rhs == 0 { return false; @@ -16,7 +16,7 @@ fn is_divisible_by(lhs: uint, rhs: uint) -> bool { } // Functions that "don't" return a value, actually return the unit type `()` -fn fizzbuzz(n: uint) -> () { +fn fizzbuzz(n: u32) -> () { if is_divisible_by(n, 15) { println!("fizzbuzz"); } else if is_divisible_by(n, 3) { @@ -30,7 +30,7 @@ fn fizzbuzz(n: uint) -> () { // When a function returns `()`, the return type can be omitted from the // signature -fn fizzbuzz_to(n: uint) { +fn fizzbuzz_to(n: u32) { for n in range(1, n + 1) { fizzbuzz(n); } diff --git a/examples/for/for.rs b/examples/for/for.rs index 8aa29024a3..c2ac3d49b0 100644 --- a/examples/for/for.rs +++ b/examples/for/for.rs @@ -1,6 +1,6 @@ fn main() { // `n` will take the values: 1, 2, ..., 100 in each iteration - for n in range(1u, 101) { + for n in range(1u32, 101) { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index 796f881bb0..8db13eb22f 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -19,10 +19,10 @@ fn main() { let pair_of_chars: Pair = Pair { first: 'a', second: 'b' }; // Implicitly specialize `Pair` - let pair_of_ints = Pair { first: 1i, second: 2 }; + let pair_of_ints = Pair { first: 1i32, second: 2 }; // Explicitly specialize `Tuple2` - let _tuple: Tuple2 = Tuple2('R', 2); + let _tuple: Tuple2 = Tuple2('R', 2); // Explicitly specialize `swap` let _swapped_pair_of_chars = swap::(pair_of_chars); diff --git a/examples/hof/hof.rs b/examples/hof/hof.rs index 5ea39e6523..8daf6014d7 100644 --- a/examples/hof/hof.rs +++ b/examples/hof/hof.rs @@ -4,13 +4,13 @@ use std::iter; fn main() { println!("Find the sum of all the squared odd numbers under 1000"); - let upper = 1000u; + let upper = 1000u32; // Imperative approach // Declare accumulator variable let mut acc = 0; // Iterate: 0, 1, 2, ... to infinity - for n in iter::count(0u, 1) { + for n in iter::count(0u32, 1) { // Square the number let n_squared = n * n; @@ -27,7 +27,7 @@ fn main() { // Functional approach let sum_of_squared_odd_numbers = // All natural numbers - iter::count(0u, 1). + iter::count(0u32, 1). // Squared map(|n| n * n). // Below upper limit @@ -39,6 +39,6 @@ fn main() { println!("functional style: {}", sum_of_squared_odd_numbers); } -fn is_odd(n: uint) -> bool { +fn is_odd(n: u32) -> bool { n % 2 == 1 } diff --git a/examples/if-else/if-else.rs b/examples/if-else/if-else.rs index 2982fefd10..1b020fe9de 100644 --- a/examples/if-else/if-else.rs +++ b/examples/if-else/if-else.rs @@ -1,5 +1,5 @@ fn main() { - let n = 5i; + let n = 5i32; if n < 0 { print!("{} is negative", n); diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index ce5ace8a17..352b582472 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -1,17 +1,17 @@ use std::mem; struct Fibonacci { - curr: uint, - next: uint, + curr: u32, + next: u32, } // Implement 'Iterator' for 'Fibonacci' impl Iterator for Fibonacci { - type Item = uint; + type Item = u32; // The 'Iterator' trait only requires the 'next' method to be defined. The // return type is 'Option', 'None' is returned when the 'Iterator' is // over, otherwise the next value is returned wrapped in 'Some' - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { let new_next = self.curr + self.next; let new_curr = mem::replace(&mut self.next, new_next); @@ -27,7 +27,7 @@ fn fibonacci() -> Fibonacci { fn main() { // Iterator that generates: 0, 1 and 2 - let mut sequence = range(0u, 3); + let mut sequence = range(0u32, 3); println!("Four consecutive `next` calls on range(0, 3)"); println!("> {:?}", sequence.next()); @@ -38,7 +38,7 @@ fn main() { // The for construct will iterate an 'Iterator' until it returns 'None'. // Every 'Some' value is unwrapped and bound to a variable. println!("Iterate over range(0, 3) using for"); - for i in range(0u, 3) { + for i in range(0u32, 3) { println!("> {}", i); } @@ -56,10 +56,10 @@ fn main() { println!("> {}", i); } - let array = [1u, 3, 3, 7]; + let array = [1u32, 3, 3, 7]; // The 'iter' method produces an 'Iterator' over an array/slice - println!("Iterate the following array {}", array.as_slice()); + println!("Iterate the following array {:?}", array.as_slice()); for i in array.iter() { println!("> {}", i); } diff --git a/examples/lifetime/explicit/explicit.rs b/examples/lifetime/explicit/explicit.rs index 0057b53cce..05605aebc5 100644 --- a/examples/lifetime/explicit/explicit.rs +++ b/examples/lifetime/explicit/explicit.rs @@ -2,7 +2,7 @@ struct Book { // `String` is a heap allocated string title: String, author: String, - year: uint, + year: i32, } fn get_title<'a>(book: &'a Book) -> &'a str { diff --git a/examples/lifetime/fn/fn.rs b/examples/lifetime/fn/fn.rs index cb0781b233..d4b1e86a15 100644 --- a/examples/lifetime/fn/fn.rs +++ b/examples/lifetime/fn/fn.rs @@ -1,14 +1,14 @@ #[derive(Show)] struct Triplet { - one: int, - two: int, - three: int, + one: i32, + two: i32, + three: i32, } impl Triplet { // First attempt: No explicit lifetimes // The compiler infers that the field and the struct have the same lifetime - fn mut_one(&mut self) -> &mut int { + fn mut_one(&mut self) -> &mut i32 { &mut self.one } @@ -16,7 +16,7 @@ impl Triplet { // references // Error! The compiler doesn't know what is the relationship between the // lifetime `structure` and the lifetime `field` - //fn mut_two<'structure, 'field>(&'structure mut self) -> &'field mut int { + //fn mut_two<'structure, 'field>(&'structure mut self) -> &'field mut i32 { //&mut self.two //} // TODO ^ Try uncommenting this method @@ -30,7 +30,7 @@ impl Triplet { // We can use a shorter name for the lifetime, it's common to use a single // letter lifetime, let's use `'s`, because it's the first letter of // structure - fn mut_three<'s>(&'s mut self) -> &'s mut int { + fn mut_three<'s>(&'s mut self) -> &'s mut i32 { &mut self.three } } diff --git a/examples/lifetime/struct/struct.rs b/examples/lifetime/struct/struct.rs index 31d9211d71..ec20f2bd94 100644 --- a/examples/lifetime/struct/struct.rs +++ b/examples/lifetime/struct/struct.rs @@ -7,8 +7,8 @@ // Second attempt: Add lifetimes to all the references struct Pair<'a, 'b> { - one: &'a mut int, - two: &'b mut int, + one: &'a mut i32, + two: &'b mut i32, } fn main() { diff --git a/examples/literals/literals.rs b/examples/literals/literals.rs index 46cfdc512b..f8d70f7dc7 100644 --- a/examples/literals/literals.rs +++ b/examples/literals/literals.rs @@ -1,10 +1,10 @@ fn main() { // Integer addition - println!("1 + 2 = {}", 1u + 2); + println!("1 + 2 = {}", 1u32 + 2); // Integer subtraction - println!("1 - 2 = {}", 1i - 2); - // TODO ^ Try changing `1i` to `1u` to see why the type is important + println!("1 - 2 = {}", 1i32 - 2); + // TODO ^ Try changing `1i32` to `1u32` to see why the type is important // Short-circuiting boolean logic println!("true AND false is {}", true && false); @@ -12,12 +12,12 @@ fn main() { println!("NOT true is {}", !true); // Bitwise operations - println!("0011 AND 0101 is {:04b}", 0b0011u & 0b0101); - println!("0011 OR 0101 is {:04b}", 0b0011u | 0b0101); - println!("0011 XOR 0101 is {:04b}", 0b0011u ^ 0b0101); - println!("1 << 5 is {}", 1u << 5); - println!("0x80 >> 2 is 0x{:x}", 0x80u >> 2); + println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101); + println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101); + println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101); + println!("1 << 5 is {}", 1u32 << 5); + println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2); // Use underscores to improve readability! - println!("One million is written as {}", 1_000_000u); + println!("One million is written as {}", 1_000_000u32); } diff --git a/examples/loop/loop.rs b/examples/loop/loop.rs index 5341cff6a0..1718b2d9eb 100644 --- a/examples/loop/loop.rs +++ b/examples/loop/loop.rs @@ -1,5 +1,5 @@ fn main() { - let mut count = 0u; + let mut count = 0u32; println!("Let's count until infinity!"); diff --git a/examples/match/guard/guard.rs b/examples/match/guard/guard.rs index 1e42350706..72e8e03336 100644 --- a/examples/match/guard/guard.rs +++ b/examples/match/guard/guard.rs @@ -1,5 +1,5 @@ fn main() { - let pair = (2i, -2); + let pair = (2i32, -2); // TODO ^ Try different values for `pair` println!("Tell me about {:?}", pair); diff --git a/examples/match/match.rs b/examples/match/match.rs index af15a7a03c..ce88c13ec3 100644 --- a/examples/match/match.rs +++ b/examples/match/match.rs @@ -1,5 +1,5 @@ fn main() { - let number: int = 13; + let number: i32 = 13; // TODO ^ Try different values for `number` println!("Tell me about {}", number); @@ -16,7 +16,7 @@ fn main() { let boolean = true; // Match is an expression too - let binary: int = match boolean { + let binary: i32 = match boolean { // The arms of a match must cover all the possible values false => 0, true => 1, diff --git a/examples/match/struct/struct.rs b/examples/match/struct/struct.rs index afa2ed8d00..224f583deb 100644 --- a/examples/match/struct/struct.rs +++ b/examples/match/struct/struct.rs @@ -1,5 +1,5 @@ fn main() { - struct Foo { x: (uint, uint), y: uint } + struct Foo { x: (u32, u32), y: u32 } // destructure members of the struct let foo = Foo { x: (1, 2), y: 3 }; diff --git a/examples/methods/methods.rs b/examples/methods/methods.rs index 41b580ceb5..4fa66d9711 100644 --- a/examples/methods/methods.rs +++ b/examples/methods/methods.rs @@ -1,3 +1,5 @@ +#![feature(box_syntax)] + use std::num::Float; // To be able to use .abs(), you must include this @@ -59,7 +61,7 @@ impl Rectangle { } // `Pair` owns resources: two heap allocated integers -struct Pair(Box, Box); +struct Pair(Box, Box); impl Pair { // This method "consumes" the resources of the caller object diff --git a/examples/move/move.rs b/examples/move/move.rs index 4da44ff5a7..c06bf8972b 100644 --- a/examples/move/move.rs +++ b/examples/move/move.rs @@ -1,5 +1,7 @@ +#![feature(box_syntax)] + // This function takes ownership of the heap allocated memory -fn destroy_box(c: Box) { +fn destroy_box(c: Box) { println!("destroying a box that contains {}", c); // `c` will be destroyed in this scope, and the memory will be freed @@ -7,7 +9,7 @@ fn destroy_box(c: Box) { fn main() { // Stack allocated integer - let x = 5u; + let x = 5u32; // "Copy" `x` into `y`, there are no resources to move let y = x; @@ -16,7 +18,7 @@ fn main() { println!("x is {}, and y is {}", x, y); // `a` is a pointer to a heap allocated integer - let a = box 5; + let a = box 5i32; println!("a contains: {}", a); diff --git a/examples/move/mut/mut.rs b/examples/move/mut/mut.rs index 4f6de6711b..ce8dcf0637 100644 --- a/examples/move/mut/mut.rs +++ b/examples/move/mut/mut.rs @@ -1,5 +1,7 @@ +#![feature(box_syntax)] + fn main() { - let immutable_box = box 5u; + let immutable_box = box 5u32; println!("immutable_box contains {}", immutable_box); diff --git a/examples/option/option.rs b/examples/option/option.rs index d76f9e2492..176055cf72 100644 --- a/examples/option/option.rs +++ b/examples/option/option.rs @@ -1,5 +1,5 @@ // An integer division that doesn't `panic!` -fn checked_division(dividend: int, divisor: int) -> Option { +fn checked_division(dividend: i32, divisor: i32) -> Option { if divisor == 0 { // Failure is represented as the `None` variant None @@ -10,7 +10,7 @@ fn checked_division(dividend: int, divisor: int) -> Option { } // This function handles a division that may not succeed -fn try_division(dividend: int, divisor: int) { +fn try_division(dividend: i32, divisor: i32) { // `Option` values can be pattern matched, just like other enums match checked_division(dividend, divisor) { None => println!("{} / {} failed!", dividend, divisor), @@ -25,8 +25,8 @@ fn main() { try_division(1, 0); // Binding `None` to a variable needs to be type annotated - let none: Option = None; - let _equivalent_none = None::; + let none: Option = None; + let _equivalent_none = None::; let optional_float = Some(0f32); diff --git a/examples/panic/panic.rs b/examples/panic/panic.rs index 3c69b04b44..37caae853d 100644 --- a/examples/panic/panic.rs +++ b/examples/panic/panic.rs @@ -1,5 +1,7 @@ +#![feature(box_syntax)] + // Re-implementation of integer division (/) -fn division(dividend: int, divisor: int) -> int { +fn division(dividend: i32, divisor: i32) -> i32 { if divisor == 0 { // Division by zero triggers a task panic panic!("division by zero"); @@ -11,7 +13,7 @@ fn division(dividend: int, divisor: int) -> int { // The `main` task fn main() { // Heap allocated integer - let _x = box 0i; + let _x = box 0i32; // This operation will trigger a task failure division(3, 0); diff --git a/examples/raii/raii.rs b/examples/raii/raii.rs index 99e6fabbc6..d480da1c6c 100644 --- a/examples/raii/raii.rs +++ b/examples/raii/raii.rs @@ -1,24 +1,26 @@ +#![feature(box_syntax)] + fn create_box() { // Allocate an integer in the heap - let _function_box = box 3i; + let _function_box = box 3i32; // `_function_box` gets destroyed here, memory gets freed } fn main() { // Allocate an integer in the heap - let _boxed_int = box 5i; + let _boxed_int = box 5i32; // new (smaller) scope { // Another heap allocated integer - let _short_lived_box = box 4i; + let _short_lived_box = box 4i32; // `_short_lived_box` gets destroyed here, memory gets freed } // Create lots of boxes - for _ in range(0u, 1_000) { + for _ in range(0u32, 1_000) { create_box(); } diff --git a/examples/staging/arg/args.rs b/examples/staging/arg/args.rs index 448b040891..2c0ef153de 100644 --- a/examples/staging/arg/args.rs +++ b/examples/staging/arg/args.rs @@ -7,5 +7,5 @@ fn main() { // The rest of the arguments are the passed command line parameters. // Call the program like this: // $ ./args arg1 arg2 - println!("I got {} arguments: {}.", args.len() - 1, args.tail()); + println!("I got {:?} arguments: {:?}.", args.len() - 1, args.tail()); } diff --git a/examples/staging/arg/getopts/testopt.rs b/examples/staging/arg/getopts/testopt.rs index da488d249b..6f10a5d8e8 100644 --- a/examples/staging/arg/getopts/testopt.rs +++ b/examples/staging/arg/getopts/testopt.rs @@ -33,6 +33,6 @@ fn main() { println!("a={}, b={}, c=\"{}\"", a, b, c); if !matches.free.is_empty() { - println!("free arguments: {}", matches.free); + println!("free arguments: {:?}", matches.free); } } diff --git a/examples/staging/arg/matching/match_args.rs b/examples/staging/arg/matching/match_args.rs index b13c719e0a..ec31bda6b1 100644 --- a/examples/staging/arg/matching/match_args.rs +++ b/examples/staging/arg/matching/match_args.rs @@ -1,10 +1,10 @@ use std::os; -fn increase(number: int) { +fn increase(number: i32) { println!("{}", number + 1); } -fn decrease(number: int) { +fn decrease(number: i32) { println!("{}", number - 1); } @@ -35,7 +35,7 @@ fn main() { // one command and one argument passed [_, ref cmd, ref num] => { // parse the number - let number: int = match num.parse() { + let number: i32 = match num.parse() { Some(n) => { n }, diff --git a/examples/staging/bench/bench.rs b/examples/staging/bench/bench.rs index 49fc3f4cbc..6459ccf656 100644 --- a/examples/staging/bench/bench.rs +++ b/examples/staging/bench/bench.rs @@ -4,10 +4,10 @@ use std::mem::replace; use test::Bencher; // bench: find the `BENCH_SIZE` first terms of the fibonacci sequence -static BENCH_SIZE: uint = 20; +static BENCH_SIZE: usize = 20; // recursive fibonacci -fn fibonacci(n: uint) -> uint { +fn fibonacci(n: usize) -> u32 { if n < 2 { 1 } else { @@ -17,13 +17,13 @@ fn fibonacci(n: uint) -> uint { // iterative fibonacci struct Fibonacci { - curr: uint, - next: uint, + curr: u32, + next: u32, } impl Iterator for Fibonacci { - type Item = uint; - fn next(&mut self) -> Option { + type Item = u32; + fn next(&mut self) -> Option { let new_next = self.curr + self.next; let new_curr = replace(&mut self.next, new_next); @@ -41,13 +41,13 @@ fn recursive_fibonacci(b: &mut Bencher) { // exact code to benchmark must be passed as a closure to the iter // method of Bencher b.iter(|| { - range(0, BENCH_SIZE).map(fibonacci).collect::>() + range(0, BENCH_SIZE).map(fibonacci).collect::>() }) } #[bench] fn iterative_fibonacci(b: &mut Bencher) { b.iter(|| { - fibonacci_sequence().take(BENCH_SIZE).collect::>() + fibonacci_sequence().take(BENCH_SIZE).collect::>() }) } diff --git a/examples/staging/hash/hashset/hashset.rs b/examples/staging/hash/hashset/hashset.rs index 904189b4f6..f3ac50aa6c 100644 --- a/examples/staging/hash/hashset/hashset.rs +++ b/examples/staging/hash/hashset/hashset.rs @@ -1,8 +1,8 @@ use std::collections::HashSet; fn main() { - let mut a: HashSet = vec!(1i, 2, 3).into_iter().collect(); - let mut b: HashSet = vec!(2i, 3, 4).into_iter().collect(); + let mut a: HashSet = vec!(1i32, 2, 3).into_iter().collect(); + let mut b: HashSet = vec!(2i32, 3, 4).into_iter().collect(); assert!(a.insert(4)); assert!(a.contains(&4)); @@ -21,16 +21,16 @@ fn main() { println!("B: {:?}", b); // Print [1, 2, 3, 4, 5] in arbitrary order - println!("Union: {}", a.union(&b).collect::>()); + println!("Union: {:?}", a.union(&b).collect::>()); // This should print [1] - println!("Difference: {}", a.difference(&b).collect::>()); + println!("Difference: {:?}", a.difference(&b).collect::>()); // Print [2, 3, 4] in arbitrary order. - println!("Intersection: {}", a.intersection(&b).collect::>()); + println!("Intersection: {:?}", a.intersection(&b).collect::>()); // Print [1, 5] - println!("Symmetric Difference: {}", - a.symmetric_difference(&b).collect::>()); + println!("Symmetric Difference: {:?}", + a.symmetric_difference(&b).collect::>()); } diff --git a/examples/staging/macros/designators.rs b/examples/staging/macros/designators.rs index d93a2cf905..dea491353c 100644 --- a/examples/staging/macros/designators.rs +++ b/examples/staging/macros/designators.rs @@ -28,11 +28,11 @@ fn main() { foo(); bar(); - print_result!(1u + 1); + print_result!(1u32 + 1); // remember that blocks are expressions print_result!({ - let x = 1u; + let x = 1u32; x * x + 2 * x - 1 }); diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry.rs index d68438148a..fd01fc09d0 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry.rs @@ -44,7 +44,7 @@ mod test { ($func: ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { - for size in range(0u, 10) { + for size in range(0u32, 10) { let mut x: Vec<_> = iter::repeat(size).take($x).collect(); let y: Vec<_> = iter::repeat(size).take($y).collect(); let z: Vec<_> = iter::repeat(size).take($z).collect(); @@ -58,7 +58,7 @@ mod test { } // test add_assign, mul_assign and sub_assign - test!(add_assign, 1u, 2u, 3u); - test!(mul_assign, 2u, 3u, 6u); - test!(sub_assign, 3u, 2u, 1u); + test!(add_assign, 1us, 2us, 3us); + test!(mul_assign, 2us, 3us, 6us); + test!(sub_assign, 3us, 2us, 1us); } diff --git a/examples/staging/macros/overload.rs b/examples/staging/macros/overload.rs index 8005bfbbad..905d5d262a 100644 --- a/examples/staging/macros/overload.rs +++ b/examples/staging/macros/overload.rs @@ -18,6 +18,6 @@ macro_rules! test { } fn main() { - test!(1i + 1 == 2i; and 2i * 2 == 4i); + test!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); test!(true; or false); } diff --git a/examples/staging/macros/repeat.rs b/examples/staging/macros/repeat.rs index 9dc603ac80..374a86e412 100644 --- a/examples/staging/macros/repeat.rs +++ b/examples/staging/macros/repeat.rs @@ -12,7 +12,7 @@ macro_rules! min { } fn main() { - println!("{}", min!(1u)); - println!("{}", min!(1u + 2 , 2u)); - println!("{}", min!(5u, 2u * 3, 4u)); + println!("{}", min!(1u32)); + println!("{}", min!(1u32 + 2 , 2u32)); + println!("{}", min!(5u32, 2u32 * 3, 4u32)); } diff --git a/examples/staging/rand/distributions.rs b/examples/staging/rand/distributions.rs index 32058305f0..819c139926 100644 --- a/examples/staging/rand/distributions.rs +++ b/examples/staging/rand/distributions.rs @@ -6,13 +6,13 @@ fn main() { let normal = Normal::new(0.0, 1.0); println!("10 samples from a normal distribution with mean 0.0 and SD 1.0"); - for _ in range(0u, 10) { + for _ in range(0u32, 10) { println!("{}", normal.ind_sample(&mut rng)); } let student = StudentT::new(5.0); println!("10 samples from a T distribution with 5 degrees of freedom"); - for _ in range(0u, 10) { + for _ in range(0u32, 10) { println!("{}", student.ind_sample(&mut rng)); } } diff --git a/examples/staging/rand/gen.rs b/examples/staging/rand/gen.rs index a6fb3d87dc..175860f96d 100644 --- a/examples/staging/rand/gen.rs +++ b/examples/staging/rand/gen.rs @@ -21,20 +21,20 @@ fn main() { let mut v: Vec = rng.gen_iter::().take(10).collect(); println!("10 randomly generated u8 values"); - println!("{}", v.as_slice()); + println!("{:?}", v.as_slice()); // `shuffle` shuffles a mutable slice in place rng.shuffle(v.as_mut_slice()); println!("shuffle previous slice"); - println!("{}", v.as_slice()); + println!("{:?}", v.as_slice()); // `choose` will sample an slice *with* replacement // i.e. the same element can be chosen more than one time println!("sample previous slice *with* replacement 10 times"); - for _ in range(0u, 10) { + for _ in range(0u32, 10) { match rng.choose(v.as_slice()) { None => panic!("slice was empty"), - Some(x) => println!("{}", x), + Some(x) => println!("{:?}", x), } } } diff --git a/examples/staging/simd/simd_add.rs b/examples/staging/simd/simd_add.rs index f29f3fc194..3e5b1d874f 100644 --- a/examples/staging/simd/simd_add.rs +++ b/examples/staging/simd/simd_add.rs @@ -22,7 +22,7 @@ fn add_assign(xs: &mut Vec, ys: &Vec) { fn simd_add_assign(xs: &mut Vec, ys: &Vec) { assert_equal_len!(xs, ys); - let size = xs.len() as int; + let size = xs.len() as isize; let chunks = size / 4; // pointer to the start of the vector data @@ -54,7 +54,7 @@ mod bench { extern crate test; use self::test::Bencher; use std::iter; - static BENCH_SIZE: uint = 10_000; + static BENCH_SIZE: usize = 10_000; macro_rules! bench { ($name:ident, $func:ident) => { diff --git a/examples/staging/test/fail.rs b/examples/staging/test/fail.rs index f90df143c6..28bb14dcce 100644 --- a/examples/staging/test/fail.rs +++ b/examples/staging/test/fail.rs @@ -1,5 +1,5 @@ #[test] #[should_fail] fn failing_test() { - assert!(1i == 2i); + assert!(1i32 == 2i32); } diff --git a/examples/structs/structs.rs b/examples/structs/structs.rs index 10e194ee0f..84178fc7ef 100644 --- a/examples/structs/structs.rs +++ b/examples/structs/structs.rs @@ -2,7 +2,7 @@ struct Nil; // A tuple struct -struct Pair(int, f64); +struct Pair(i32, f64); // A struct with two fields struct Point { @@ -42,5 +42,5 @@ fn main() { // Destructure a tuple struct let Pair(integer, decimal) = pair; - println!("pair contains {} and {}", integer, decimal); + println!("pair contains {:?} and {:?}", integer, decimal); } diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index 7e7057e7e7..033b0d813e 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,6 +1,6 @@ use std::thread::Thread; -static NTHREADS: int = 10; +static NTHREADS: i32 = 10; // This is the `main` thread fn main() { diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 0a07ce7afc..d7587849a2 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -32,7 +32,7 @@ fn main() { let metronome: mpsc::Receiver<()> = timer.periodic(interval); println!("Countdown"); - for i in iter::range_step(5i, 0, -1) { + for i in iter::range_step(5i32, 0, -1) { // This loop will run once every second let _ = metronome.recv(); diff --git a/examples/trait/deriving/deriving.rs b/examples/trait/deriving/deriving.rs index a8b27bf950..a193378eb8 100644 --- a/examples/trait/deriving/deriving.rs +++ b/examples/trait/deriving/deriving.rs @@ -4,7 +4,7 @@ struct Centimeters(f64); // A tuple struct that can be printed #[derive(Show)] -struct Inches(int); +struct Inches(i32); impl Inches { fn to_centimeters(&self) -> Centimeters { @@ -15,7 +15,7 @@ impl Inches { } // A vanilla tuple struct -struct Seconds(int); +struct Seconds(i32); fn main() { let _one_second = Seconds(1); diff --git a/examples/tuples/tuples.rs b/examples/tuples/tuples.rs index fe8322bb66..835408c5d2 100644 --- a/examples/tuples/tuples.rs +++ b/examples/tuples/tuples.rs @@ -1,5 +1,5 @@ // Tuples can be used as function arguments and as return values -fn reverse(pair: (int, bool)) -> (bool, int) { +fn reverse(pair: (i32, bool)) -> (bool, i32) { // `let` can be used to bind the members of a tuple to variables let (integer, boolean) = pair; @@ -30,6 +30,6 @@ fn main() { // To create one element tuples, the comma is required to tell them apart // from a literal surrounded by parentheses - println!("one element tuple: {:?}", (5u,)); - println!("just an integer: {:?}", (5u)); + println!("one element tuple: {:?}", (5u32,)); + println!("just an integer: {:?}", (5u32)); } diff --git a/examples/type/inference/inference.rs b/examples/type/inference/inference.rs index 54131a2e38..6f5db13405 100644 --- a/examples/type/inference/inference.rs +++ b/examples/type/inference/inference.rs @@ -12,5 +12,5 @@ fn main() { // Aha! Now the compiler knows that `vec` is a vector of `u8`s (`Vec`) // TODO ^ Try commenting out the `vec.push(elem)` line - println!("{}", vec); + println!("{:?}", vec); } diff --git a/examples/type/literals/literals.rs b/examples/type/literals/literals.rs index f06230db83..b690b749ef 100644 --- a/examples/type/literals/literals.rs +++ b/examples/type/literals/literals.rs @@ -1,7 +1,7 @@ fn main() { // Suffixed literals, their types are known at initialization let x = 1u8; - let y = 2u; + let y = 2u32; let z = 3f32; // Unsuffixed literal, their types depend on how they are used diff --git a/examples/variables/variables.rs b/examples/variables/variables.rs index 59067e75e6..f5c486c318 100644 --- a/examples/variables/variables.rs +++ b/examples/variables/variables.rs @@ -1,18 +1,18 @@ fn main() { - let an_integer = 1u; + let an_integer = 1u32; let a_boolean = true; let unit = (); // copy `an_integer` into `copied_integer` let copied_integer = an_integer; - println!("An integer: {}", copied_integer); - println!("A boolean: {}", a_boolean); - println!("Meet the unit value: {}", unit); + println!("An integer: {:?}", copied_integer); + println!("A boolean: {:?}", a_boolean); + println!("Meet the unit value: {:?}", unit); // The compiler warns about unused variables; these warnings can be // silenced by prefixing the variable name with an underscore - let _unused_variable = 3u; - let noisy_unused_variable = 2u; + let _unused_variable = 3u32; + let noisy_unused_variable = 2u32; // FIXME ^ Prefix with an underscore to suppress the warning } diff --git a/examples/while/while.rs b/examples/while/while.rs index c0396d31df..df9c98e30e 100644 --- a/examples/while/while.rs +++ b/examples/while/while.rs @@ -1,6 +1,6 @@ fn main() { // A counter variable - let mut n = 1u; + let mut n = 1u32; // Loop while `n` is less than 101 while n < 101 { From 60aa041d1ab9a57dbae5682f590517eec4070049 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sat, 10 Jan 2015 21:08:36 -0200 Subject: [PATCH 0038/1122] Use :? to format when deriving Show --- examples/bounds/bounds.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index 2c104e1100..d71d6e051f 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -48,11 +48,11 @@ fn main() { let v1 = Vec2 { x: 1.2_f32, y: 3.4 }; let v2 = Vec2 { x: 5.6_f32, y: 7.8 }; - println!("{} + {} = {}", v1, v2, v1 + v2); - println!("{} - {} = {}", v1, v2, v1 - v2); - println!("{} ⋅ {} = {}", v1, v2, v1.dot(v2)); + println!("{:?} + {:?} = {:?}", v1, v2, v1 + v2); + println!("{:?} - {:?} = {:?}", v1, v2, v1 - v2); + println!("{:?} ⋅ {:?} = {:?}", v1, v2, v1.dot(v2)); // Error! `char` doesn't implement the `Add` trait - println!("{}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' }); + println!("{:?}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' }); // FIXME ^ Comment out this line } From 28b456ca5286a3bb8317d074aa2caf45f1eb6dfe Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 10 Jan 2015 18:02:48 -0800 Subject: [PATCH 0039/1122] Fix #[derive(Copy)] on borrow/mut/mut.rs --- examples/borrow/mut/mut.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/borrow/mut/mut.rs b/examples/borrow/mut/mut.rs index c6d9adc41d..3c085a7f27 100644 --- a/examples/borrow/mut/mut.rs +++ b/examples/borrow/mut/mut.rs @@ -1,4 +1,5 @@ #[allow(dead_code)] +#[derive(Copy)] struct Book { // `&'static str` is a reference to a string allocated in read only memory author: &'static str, From 22d9fd00c595e8ecb437ff137eb87afa2b8cf43c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 11 Jan 2015 01:30:47 -0500 Subject: [PATCH 0040/1122] Replace 'deriving' with 'derive' --- examples/generics/phantom/input.md | 2 +- examples/staging/hash/alt-key-types/input.md | 2 +- examples/staging/rand/{deriving.rs => derive.rs} | 0 examples/staging/rand/input.md | 6 +++--- examples/structure.json | 2 +- examples/trait/{deriving/deriving.rs => derive/derive.rs} | 0 examples/trait/{deriving => derive}/input.md | 4 ++-- src/example.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) rename examples/staging/rand/{deriving.rs => derive.rs} (100%) rename examples/trait/{deriving/deriving.rs => derive/derive.rs} (100%) rename examples/trait/{deriving => derive}/input.md (95%) diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 6646fcdd09..e9057cdb91 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -6,6 +6,6 @@ at compile time; they have no run-time behavior. {phantom.play} ###See also: -[Deriving](http://rustbyexample.com/trait/deriving.html), +[Derive](http://rustbyexample.com/trait/derive.html), [struct](http://rustbyexample.com/structs.html), and [TupleStructs](http://rustbyexample.com/structs.html) diff --git a/examples/staging/hash/alt-key-types/input.md b/examples/staging/hash/alt-key-types/input.md index af43d97438..e22ffc4de4 100644 --- a/examples/staging/hash/alt-key-types/input.md +++ b/examples/staging/hash/alt-key-types/input.md @@ -16,7 +16,7 @@ if their contained type also respectively implements `Eq` and `Hash`. For example, `Vec` will implement `Hash` if `T` implements `Hash`. You can easily implement `Eq` and `Hash` for a custom type with just one line: -`#[deriving(PartialEq, Eq, Hash)]` +`#[derive(PartialEq, Eq, Hash)]` The compiler will do the rest. If you want more control over the details, you can implement `Eq` and/or `Hash` yourself. diff --git a/examples/staging/rand/deriving.rs b/examples/staging/rand/derive.rs similarity index 100% rename from examples/staging/rand/deriving.rs rename to examples/staging/rand/derive.rs diff --git a/examples/staging/rand/input.md b/examples/staging/rand/input.md index 76419077f1..d6316905e3 100644 --- a/examples/staging/rand/input.md +++ b/examples/staging/rand/input.md @@ -14,9 +14,9 @@ normal, uniform, Student's T, Chi squared, Gamma, etc. {distributions.out} -The `deriving` attribute can be used to implement the `Rand` trait for custom +The `derive` attribute can be used to implement the `Rand` trait for custom types, this allows generation of random values of custom types. -{deriving.rs} +{derive.rs} -{deriving.out} +{derive.out} diff --git a/examples/structure.json b/examples/structure.json index 6ed84b3139..7ff19be161 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -78,7 +78,7 @@ { "id": "option", "title": "`Option`", "children": null }, { "id": "array", "title": "Arrays and Slices", "children": null }, { "id": "trait", "title": "Traits", "children": [ - { "id": "deriving", "title": "Deriving", "children": null } + { "id": "derive", "title": "Derive", "children": null } ] }, { "id": "ops", "title": "Operator Overloading", "children": null }, { "id": "bounds", "title": "Bounds", "children": null }, diff --git a/examples/trait/deriving/deriving.rs b/examples/trait/derive/derive.rs similarity index 100% rename from examples/trait/deriving/deriving.rs rename to examples/trait/derive/derive.rs diff --git a/examples/trait/deriving/input.md b/examples/trait/derive/input.md similarity index 95% rename from examples/trait/deriving/input.md rename to examples/trait/derive/input.md index 8a4b3a5bab..ff4ef83e83 100644 --- a/examples/trait/deriving/input.md +++ b/examples/trait/derive/input.md @@ -1,8 +1,8 @@ The compiler is capable of providing basic implementations for some traits via -the `#[deriving]` [attribute][attribute]. These traits can still be +the `#[derive]` [attribute][attribute]. These traits can still be manually implemented if a more complex behavior is required. -{deriving.play} +{derive.play} This is a list of the "derivable" traits: * Comparison traits: diff --git a/src/example.rs b/src/example.rs index bbddde3f0f..86bd25a115 100644 --- a/src/example.rs +++ b/src/example.rs @@ -4,7 +4,7 @@ use serialize::{Decodable,json}; use std::iter::AdditiveIterator; use std::iter::repeat; -#[deriving(Decodable)] +#[derive(Decodable)] pub struct Example { children: Option>, id: String, From e7ffa68f09ff57c1b936f0db811d44f455a786f3 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sun, 11 Jan 2015 11:37:55 -0800 Subject: [PATCH 0041/1122] Fix generics/phantom type comments --- examples/generics/phantom/units/units.rs | 36 +++++++++++++++--------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index d046dc1716..e8d35597f9 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -1,24 +1,34 @@ use std::ops::Add; -// Null enumerations to define unit types +/// Null enumerations to define unit types #[derive(Show, Copy)] -enum Inch {} +struct Inch; #[derive(Show, Copy)] -enum Mm {} +struct Mm; -// Length is phantom type with hidden parameter `Unit` +/// Length is phantom type with hidden parameter `Unit` #[derive(Show, Copy)] struct Length(T,); -// `impl X for Y {}` reads "implement `X` Trait for Type `Y`" -// So, this implements the `Add` Trait for Type `Length` -// The `Add` Trait overloads the addition operator -// so elements can be added together. -// `X: Y` applies a restriction to `X` and only allows operations -// to `X` if `X` implements the Trait `Y`. -// This means that this `impl` defines `Add` only for `T` when -// two `T's` can be added together and the result is of -// Type `T`: (`T: Add`) +/// impl X for Y {} means "implement the trait `X` for the Type `Y`" +/// The following lines implement the `Add` trait for Length. +/// +/// The `` after `impl` declares two generic +/// types, `Unit`, which can be any type, and `T`, which is a type that +/// must implement both traits `Copy` (which means no need to borrow, +/// move, or clone; you can just pass in a variable, and both the caller +/// and callee will own their own copy), and the trait `Add`. +/// +/// `Add` means that the type implements Add, taking in a T +/// (meaning an i32 plus an i32, or an f64 plus an f64, etc.), and giving +/// back a T (i32 + i32 = i32). +/// +/// So, this impl implements `Add` for `Length`, +/// which means you can add a `Length` to another `Length` of the same type. +/// +/// `type Output = Length` means that this impl gives back a +/// `Length`, so that +/// `Length + Length = Length` impl + Copy> Add> for Length { type Output = Length; From f9c399968552eebba42ba7b666f6e218f9cec82f Mon Sep 17 00:00:00 2001 From: nettok Date: Sun, 11 Jan 2015 13:18:38 -0600 Subject: [PATCH 0042/1122] trait/deriving: Show requires {:?} instead of {} --- examples/trait/derive/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index ff4ef83e83..a600ba0f4b 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -26,7 +26,7 @@ This is a list of the "derivable" traits: * [`FromPrimitive`][from-primitive], to create an instance from a numeric primitive. * [`Show`][show], to - format a value using the `{}` formatter. + format a value using the `{:?}` formatter. [attribute]: /attribute.html [eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html From 342447ad3dc96089150c13dbd0374eb1e663da95 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sun, 11 Jan 2015 21:57:17 -0800 Subject: [PATCH 0043/1122] remove gitbook@0.7.1, b/c it is installed in make --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index acb9509a4d..839b2c0fde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: node_js install: - - npm install gitbook@0.7.1 -g - curl -s https://static.rust-lang.org/rustup.sh | sudo sh > /dev/null script: From 91b74f61854d1573392ac2c34545b497ebc9c2a2 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 12 Jan 2015 09:37:56 -0500 Subject: [PATCH 0044/1122] Add target to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 20620ac0df..831b59a7bb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ stage/* node_modules/* !node_modules/gitbook-plugin-rust-playpen node_modules/gitbook-plugin-rust-playpen/book/ace +target From cf0b4f606d9c250bbc289953097070fcf9c94ace Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 9 Jan 2015 11:56:06 -0500 Subject: [PATCH 0045/1122] Port src/update to cargo This builds as of rustc 1.0.0-dev (6354d60ed 2015-01-08 20:59:48 +0000) --- Cargo.lock | 27 +++++++++++++++++++++++++++ Cargo.toml | 12 ++++++++++++ src/example.rs | 11 ++++++----- src/{update.rs => main.rs} | 20 +++++++++++++------- src/markdown.rs | 11 ++++++----- 5 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml rename src/{update.rs => main.rs} (78%) diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000000..ddf97d27c3 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,27 @@ +[root] +name = "foo" +version = "0.0.1" +dependencies = [ + "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex_macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex_macros" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-serialize" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000..55c0e184a0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] + +name = "foo" +version = "0.0.1" +authors = ["Jorge Aparicio ", + "Steve Klabnik "] + +[dependencies] + +rustc-serialize = "*" +regex = "*" +regex_macros = "*" diff --git a/src/example.rs b/src/example.rs index 86bd25a115..c59bbaf77d 100644 --- a/src/example.rs +++ b/src/example.rs @@ -1,10 +1,11 @@ use file; use markdown::Markdown; -use serialize::{Decodable,json}; +use rustc_serialize::{Decodable,json}; use std::iter::AdditiveIterator; use std::iter::repeat; +use std::sync::mpsc; -#[derive(Decodable)] +#[derive(RustcDecodable)] pub struct Example { children: Option>, id: String, @@ -15,7 +16,7 @@ impl Example { pub fn get_list() -> Vec { match file::read(&Path::new("examples/structure.json")) { Err(why) => panic!("{}", why), - Ok(string) => match json::from_str(string.as_slice()) { + Ok(string) => match json::Json::from_str(string.as_slice()) { Err(_) => panic!("structure.json is not valid json"), Ok(json) => { match Decodable::decode(&mut json::Decoder::new(json)) { @@ -36,7 +37,7 @@ impl Example { pub fn process(&self, number: Vec, - tx: Sender<(Vec, String)>, + tx: mpsc::Sender<(Vec, String)>, indent: uint, prefix: String) { @@ -66,7 +67,7 @@ impl Example { }, }; - tx.send((number.clone(), entry)); + let _ = tx.send((number.clone(), entry)); match self.children { None => {}, diff --git a/src/update.rs b/src/main.rs similarity index 78% rename from src/update.rs rename to src/main.rs index 3eb75b011a..d7d06e9a32 100644 --- a/src/update.rs +++ b/src/main.rs @@ -1,13 +1,19 @@ #![deny(warnings)] -#![feature(phase)] +#![feature(int_uint)] +#![feature(plugin)] + +#![allow(unstable)] extern crate regex; -#[phase(plugin)] + +#[plugin] extern crate regex_macros; -extern crate serialize; + +extern crate "rustc-serialize" as rustc_serialize; use example::Example; use std::thread::Thread; +use std::sync::mpsc; mod example; mod file; @@ -16,22 +22,22 @@ mod playpen; fn main() { let examples = Example::get_list(); - let (tx, rx) = channel(); + let (tx, rx) = mpsc::channel(); let mut nexamples = 0; for (i, example) in examples.into_iter().enumerate() { let tx = tx.clone(); let count = example.count(); - Thread::spawn(move || { + let _ = Thread::scoped(move || { example.process(vec!(i + 1), tx, 0, String::new()); - }).detach(); + }); nexamples += count; } let mut entries = range(0, nexamples).map(|_| { - rx.recv() + rx.recv().unwrap() }).collect::, String)>>(); entries.sort_by(|&(ref i, _), &(ref j, _)| i.cmp(j)); diff --git a/src/markdown.rs b/src/markdown.rs index 829fd694cf..121d6df911 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -1,6 +1,7 @@ use file; use playpen; use std::iter::repeat; +use regex::Regex; pub struct Markdown<'a, 'b> { content: String, @@ -48,7 +49,7 @@ impl<'a, 'b> Markdown<'a, 'b> { fn insert_sources(&mut self) -> Result<(), String> { let id = self.id; let prefix = self.prefix; - let re = regex!(r"\{(.*\.rs)\}"); + let re = Regex::new(r"\{(.*\.rs)\}").unwrap(); let mut table = Vec::new(); for line in self.content.as_slice().lines() { @@ -84,7 +85,7 @@ impl<'a, 'b> Markdown<'a, 'b> { fn insert_outputs(&mut self) -> Result<(), String> { let id = self.id; let prefix = self.prefix; - let r = regex!(r"\{(.*)\.out\}"); + let r = Regex::new(r"\{(.*)\.out\}").unwrap(); let dir = Path::new(format!("bin/{}/{}", prefix, id)); @@ -96,9 +97,9 @@ impl<'a, 'b> Markdown<'a, 'b> { None => {}, Some(captures) => { let src = captures.at(1); - let input = format!("{{{}.out}}", src); + let input = format!("{{{:?}.out}}", src); let s = try!(file::run(prefix, id, src.unwrap())); - let s = format!("```\n$ rustc {0}.rs && ./{0}\n{1}```", + let s = format!("```\n$ rustc {0:?}.rs && ./{0:?}\n{1:?}```", src, s); table.push((input, s)); @@ -117,7 +118,7 @@ impl<'a, 'b> Markdown<'a, 'b> { fn insert_playpen_links(&mut self) -> Result<(), String> { let id = self.id; let prefix = self.prefix; - let re = regex!(r"\{(.*)\.play\}"); + let re = Regex::new(r"\{(.*)\.play\}").unwrap(); let mut once_ = false; let mut table = Vec::new(); From d37caaec153350e4c10e4e44e24de32d61a45bfd Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 12 Jan 2015 09:40:57 -0500 Subject: [PATCH 0046/1122] remove regex_macros dep --- Cargo.lock | 9 --------- Cargo.toml | 1 - src/main.rs | 3 --- 3 files changed, 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddf97d27c3..f02c5c6ab4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,6 @@ name = "foo" version = "0.0.1" dependencies = [ "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex_macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -12,14 +11,6 @@ name = "regex" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "regex_macros" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-serialize" version = "0.2.7" diff --git a/Cargo.toml b/Cargo.toml index 55c0e184a0..27b862a008 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,3 @@ authors = ["Jorge Aparicio ", rustc-serialize = "*" regex = "*" -regex_macros = "*" diff --git a/src/main.rs b/src/main.rs index d7d06e9a32..0e6b4b5399 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,9 +6,6 @@ extern crate regex; -#[plugin] -extern crate regex_macros; - extern crate "rustc-serialize" as rustc_serialize; use example::Example; From 17f5b135b791af9241c3630fd56efb58ee0006ff Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 12 Jan 2015 09:41:43 -0500 Subject: [PATCH 0047/1122] Fix package name from foo to update --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f02c5c6ab4..204d62fd0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,5 @@ [root] -name = "foo" +name = "update" version = "0.0.1" dependencies = [ "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 27b862a008..4a5aea264c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "foo" +name = "update" version = "0.0.1" authors = ["Jorge Aparicio ", "Steve Klabnik "] From 06f0dfd4531df70153fe7b91cd19ccc968ba577e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 12 Jan 2015 09:43:00 -0500 Subject: [PATCH 0048/1122] Use cargo in makefile --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fc083586f9..26deb55f47 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,7 @@ srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) all: ./setup-stage.sh - $(RUSTC) src/update.rs --out-dir bin - bin/update + cargo run book: node_modules/gitbook $(GITBOOK) build stage From 99d690f8b6576e174116fd7f30d0b31a38603867 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 12 Jan 2015 09:48:07 -0500 Subject: [PATCH 0049/1122] Make all lines less than 80 characters --- src/markdown.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/markdown.rs b/src/markdown.rs index 121d6df911..d33cd1d002 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -99,7 +99,9 @@ impl<'a, 'b> Markdown<'a, 'b> { let src = captures.at(1); let input = format!("{{{:?}.out}}", src); let s = try!(file::run(prefix, id, src.unwrap())); - let s = format!("```\n$ rustc {0:?}.rs && ./{0:?}\n{1:?}```", + let s = format!("``` \n\ + $ rustc {0:?}.rs && ./{0:?}\n{1:?}\n\ + ```", src, s); table.push((input, s)); From ae80e72c67f851e4bbc6cefcc4ddef65a922a731 Mon Sep 17 00:00:00 2001 From: joshua stein Date: Mon, 12 Jan 2015 11:21:22 -0600 Subject: [PATCH 0050/1122] literals: improve grammar --- examples/literals/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/literals/input.md b/examples/literals/input.md index 22cc945393..aadc860767 100644 --- a/examples/literals/input.md +++ b/examples/literals/input.md @@ -7,7 +7,7 @@ notation using either of these prefixes: `0x`, `0o` or `0b`. Underscores can be inserted in numeric literals to improve readability, e.g. `1_000` is the same as `1000`, and `0.000_001` is the same as `0.000001`. -We need to tell the compiler what is the type of the literals we use. For now, +We need to tell the compiler the type of the literals we use. For now, we'll use the `u` suffix to indicate that the literal is an unsigned integer, and the `i` suffix to indicate that it's a signed integer. We'll cover the type system in [another chapter][type], and give more details about type From 87c183392d00f6b9a6665efc125c60cd575d4686 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 12 Jan 2015 15:27:44 -0200 Subject: [PATCH 0051/1122] Use ... notation to avoid range unstable warning --- examples/iter/iter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index 352b582472..bcd532c287 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -27,7 +27,7 @@ fn fibonacci() -> Fibonacci { fn main() { // Iterator that generates: 0, 1 and 2 - let mut sequence = range(0u32, 3); + let mut sequence = 0..3; println!("Four consecutive `next` calls on range(0, 3)"); println!("> {:?}", sequence.next()); @@ -38,7 +38,7 @@ fn main() { // The for construct will iterate an 'Iterator' until it returns 'None'. // Every 'Some' value is unwrapped and bound to a variable. println!("Iterate over range(0, 3) using for"); - for i in range(0u32, 3) { + for i in 0..3 { println!("> {}", i); } From f1768d8af5a1dd9c71a269a9cbeef441f2b7f933 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 12 Jan 2015 21:12:22 -0500 Subject: [PATCH 0052/1122] Move examples into separate chapters. Enable playpen. --- .../macros/{ => designators}/designators.rs | 0 examples/staging/macros/designators/input.md | 4 ++ examples/staging/macros/{ => dry}/dry.rs | 3 ++ examples/staging/macros/dry/input.md | 15 +++++++ examples/staging/macros/input.md | 43 +------------------ examples/staging/macros/overload/input.md | 3 ++ .../staging/macros/{ => overload}/overload.rs | 0 examples/staging/macros/repeat/input.md | 5 +++ .../staging/macros/{ => repeat}/repeat.rs | 0 examples/structure.json | 7 ++- 10 files changed, 37 insertions(+), 43 deletions(-) rename examples/staging/macros/{ => designators}/designators.rs (100%) create mode 100644 examples/staging/macros/designators/input.md rename examples/staging/macros/{ => dry}/dry.rs (95%) create mode 100644 examples/staging/macros/dry/input.md create mode 100644 examples/staging/macros/overload/input.md rename examples/staging/macros/{ => overload}/overload.rs (100%) create mode 100644 examples/staging/macros/repeat/input.md rename examples/staging/macros/{ => repeat}/repeat.rs (100%) diff --git a/examples/staging/macros/designators.rs b/examples/staging/macros/designators/designators.rs similarity index 100% rename from examples/staging/macros/designators.rs rename to examples/staging/macros/designators/designators.rs diff --git a/examples/staging/macros/designators/input.md b/examples/staging/macros/designators/input.md new file mode 100644 index 0000000000..be5ad57116 --- /dev/null +++ b/examples/staging/macros/designators/input.md @@ -0,0 +1,4 @@ +The arguments of a macro are prefixed by a dollar sign `$` and type annotated +with a *designator*: + +{designators.play} diff --git a/examples/staging/macros/dry.rs b/examples/staging/macros/dry/dry.rs similarity index 95% rename from examples/staging/macros/dry.rs rename to examples/staging/macros/dry/dry.rs index fd01fc09d0..b7dba8b3f7 100644 --- a/examples/staging/macros/dry.rs +++ b/examples/staging/macros/dry/dry.rs @@ -2,6 +2,8 @@ use std::iter; use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { + // The `tt` (token tree) designator is used for + // operators and tokens ($a:ident, $b: ident, $func:ident, $op:tt) => { assert!($a.len() == $b.len(), "{}: dimension mismatch: {:?} {} {:?}", @@ -62,3 +64,4 @@ mod test { test!(mul_assign, 2us, 3us, 6us); test!(sub_assign, 3us, 2us, 1us); } + diff --git a/examples/staging/macros/dry/input.md b/examples/staging/macros/dry/input.md new file mode 100644 index 0000000000..01ea8e98b9 --- /dev/null +++ b/examples/staging/macros/dry/input.md @@ -0,0 +1,15 @@ +Macros allow writing DRY code, by factoring out the common parts of functions +and/or test suites. Here is an example that implements and tests the `+=`, `*=` +and `-=` operators on `Vec`. + +{dry.play} + +``` +$ rustc --test dry.rs && ./dry +running 3 tests +test test::mul_assign ... ok +test test::add_assign ... ok +test test::sub_assign ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured +``` diff --git a/examples/staging/macros/input.md b/examples/staging/macros/input.md index 729882d652..a3eb6c12d2 100644 --- a/examples/staging/macros/input.md +++ b/examples/staging/macros/input.md @@ -5,45 +5,4 @@ expanded into source code that gets compiled with the rest of the program. Macros are created using the `macro_rules!` macro. -{simple.rs} - -{simple.out} - -The arguments of a macro are prefixed by a dollar sign `$` and type annotated -with a *designator*. - -{designators.rs} - -{designators.out} - -Macros can be overloaded to accept different combinations of arguments. - -{overload.rs} - -{overload.out} - -Macros can use `+` in the argument list, to indicate that an argument may -repeat at least once, or `*`, to indicate that the argument may repeat zero or -more times. - -{repeat.rs} - -{repeat.out} - -Macros allow writing DRY code, by factoring out the common parts of functions -and/or test suites. Here is an example that implements and tests the `+=`, `*=` -and `-=` operators on `Vec`. - -{dry.rs} - -{dry.out} - -``` -$ rustc --test dry.rs && ./dry -running 3 tests -test test::mul_assign ... ok -test test::add_assign ... ok -test test::sub_assign ... ok - -test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured -``` +{simple.play} diff --git a/examples/staging/macros/overload/input.md b/examples/staging/macros/overload/input.md new file mode 100644 index 0000000000..940c2c122b --- /dev/null +++ b/examples/staging/macros/overload/input.md @@ -0,0 +1,3 @@ +Macros can be overloaded to accept different combinations of arguments. + +{overload.play} diff --git a/examples/staging/macros/overload.rs b/examples/staging/macros/overload/overload.rs similarity index 100% rename from examples/staging/macros/overload.rs rename to examples/staging/macros/overload/overload.rs diff --git a/examples/staging/macros/repeat/input.md b/examples/staging/macros/repeat/input.md new file mode 100644 index 0000000000..13ff391f7b --- /dev/null +++ b/examples/staging/macros/repeat/input.md @@ -0,0 +1,5 @@ +Macros can use `+` in the argument list, to indicate that an argument may +repeat at least once, or `*`, to indicate that the argument may repeat zero or +more times. + +{repeat.play} diff --git a/examples/staging/macros/repeat.rs b/examples/staging/macros/repeat/repeat.rs similarity index 100% rename from examples/staging/macros/repeat.rs rename to examples/staging/macros/repeat/repeat.rs diff --git a/examples/structure.json b/examples/structure.json index 7ff19be161..6d556bc6f3 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -112,7 +112,12 @@ { "id": "doc-comment", "title": "Doc Comments", "children": null } ] }, { "id": "ffi", "title": "Foreign Function Interface", "children": null }, - { "id": "macros", "title": "macro_rules!", "children": null }, + { "id": "macros", "title": "macro_rules!", "children": [ + { "id": "designators", "title": "Designators", "children": null }, + { "id": "overload", "title": "Overload", "children": null }, + { "id": "repeat", "title": "Repeat", "children": null }, + { "id": "dry", "title": "DRY", "children": null } + ] }, { "id": "arg", "title": "Program arguments", "children": [ { "id": "matching", "title": "Argument parsing", "children": null }, { "id": "getopts", "title": "`getopts`", "children": null } From 8e04d646791db1072e67b84a15f4be8828e84742 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 12 Jan 2015 22:05:33 -0500 Subject: [PATCH 0053/1122] Macros: close braces from `{}` to `()` --- examples/staging/macros/designators/designators.rs | 8 ++++---- examples/staging/macros/dry/dry.rs | 8 ++++---- examples/staging/macros/overload/overload.rs | 8 ++++---- examples/staging/macros/repeat/repeat.rs | 8 +++----- examples/staging/macros/simple.rs | 4 ++-- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/examples/staging/macros/designators/designators.rs b/examples/staging/macros/designators/designators.rs index dea491353c..8e211c7c0e 100644 --- a/examples/staging/macros/designators/designators.rs +++ b/examples/staging/macros/designators/designators.rs @@ -1,14 +1,14 @@ macro_rules! create_function { // this macro takes an argument of "type" `ident` // the `ident` designator is used for variable/function names - ($func_name:ident) => { + ($func_name:ident) => ( // this macro creates a function with name `$func_name` fn $func_name() { // the stringify! macro converts an `ident` into a string println!("You called {}()", stringify!($func_name)) } - } + ) } create_function!(foo); @@ -16,12 +16,12 @@ create_function!(bar); macro_rules! print_result { // the `expr` designator is used for expressions - ($expression:expr) => { + ($expression:expr) => ( // stringify! will convert the expression *as it is* into a string println!("{} = {}", stringify!($expression), $expression) - } + ) } fn main() { diff --git a/examples/staging/macros/dry/dry.rs b/examples/staging/macros/dry/dry.rs index b7dba8b3f7..f8204ac512 100644 --- a/examples/staging/macros/dry/dry.rs +++ b/examples/staging/macros/dry/dry.rs @@ -4,18 +4,18 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for // operators and tokens - ($a:ident, $b: ident, $func:ident, $op:tt) => { + ($a:ident, $b: ident, $func:ident, $op:tt) => ( assert!($a.len() == $b.len(), "{}: dimension mismatch: {:?} {} {:?}", stringify!($func), ($a.len(),), stringify!($op), ($b.len(),)); - } + ) } macro_rules! op { - ($func:ident, $bound:ident, $op:tt, $method:ident) => { + ($func:ident, $bound:ident, $op:tt, $method:ident) => ( fn $func + Copy>(xs: &mut Vec, ys: &Vec) { assert_equal_len!(xs, ys, $func, $op); @@ -24,7 +24,7 @@ macro_rules! op { // *x = x.$method(*y); } } - } + ) } // implement add_assign, mul_assign, and sub_assign functions diff --git a/examples/staging/macros/overload/overload.rs b/examples/staging/macros/overload/overload.rs index 905d5d262a..8e07a25370 100644 --- a/examples/staging/macros/overload/overload.rs +++ b/examples/staging/macros/overload/overload.rs @@ -2,19 +2,19 @@ macro_rules! test { // the arguments don't need to be separated by a comma // any template can be used - ($left:expr; and $right:expr) => { println!("{} and {} is {}", + ($left:expr; and $right:expr) => ( stringify!($left), stringify!($right), $left && $right) - }; + ); // ^ each arm must be ended with a semicolon - ($left:expr; or $right:expr) => { println!("{} or {} is {}", + ($left:expr; or $right:expr) => ( stringify!($left), stringify!($right), $left || $right) - }; + ); } fn main() { diff --git a/examples/staging/macros/repeat/repeat.rs b/examples/staging/macros/repeat/repeat.rs index 374a86e412..2611b75403 100644 --- a/examples/staging/macros/repeat/repeat.rs +++ b/examples/staging/macros/repeat/repeat.rs @@ -1,14 +1,12 @@ // min! will calculate the minimum of any number of arguments macro_rules! min { // base case - ($x:expr) => { - $x - }; + ($x:expr) => ($x); // `$x` followed by at least one `$y,` - ($x:expr, $($y:expr),+) => { + ($x:expr, $($y:expr),+) => ( // call min! on the tail `$y` std::cmp::min($x, min!($($y),+)) - } + ) } fn main() { diff --git a/examples/staging/macros/simple.rs b/examples/staging/macros/simple.rs index a5731e454b..1f7b742d79 100644 --- a/examples/staging/macros/simple.rs +++ b/examples/staging/macros/simple.rs @@ -1,10 +1,10 @@ // This is the simplest macro, `say_hello` is the name of the macro macro_rules! say_hello { // `()` indicates that the macro takes no argument - () => { + () => ( // the macro will expand into the contents of this block println!("Hello!"); - } + ) } fn main() { From aa6b08cd7823cf53b5d8c49f4b163bd5e0dbddee Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 12 Jan 2015 22:08:06 -0500 Subject: [PATCH 0054/1122] Macros: println! from `{}` for `{:?}` --- examples/staging/macros/designators/designators.rs | 4 ++-- examples/staging/macros/dry/dry.rs | 2 +- examples/staging/macros/overload/overload.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/staging/macros/designators/designators.rs b/examples/staging/macros/designators/designators.rs index 8e211c7c0e..b6dd511b9e 100644 --- a/examples/staging/macros/designators/designators.rs +++ b/examples/staging/macros/designators/designators.rs @@ -5,7 +5,7 @@ macro_rules! create_function { // this macro creates a function with name `$func_name` fn $func_name() { // the stringify! macro converts an `ident` into a string - println!("You called {}()", + println!("You called {:?}()", stringify!($func_name)) } ) @@ -18,7 +18,7 @@ macro_rules! print_result { // the `expr` designator is used for expressions ($expression:expr) => ( // stringify! will convert the expression *as it is* into a string - println!("{} = {}", + println!("{:?} = {:?}", stringify!($expression), $expression) ) diff --git a/examples/staging/macros/dry/dry.rs b/examples/staging/macros/dry/dry.rs index f8204ac512..15f0094b7c 100644 --- a/examples/staging/macros/dry/dry.rs +++ b/examples/staging/macros/dry/dry.rs @@ -6,7 +6,7 @@ macro_rules! assert_equal_len { // operators and tokens ($a:ident, $b: ident, $func:ident, $op:tt) => ( assert!($a.len() == $b.len(), - "{}: dimension mismatch: {:?} {} {:?}", + "{:?}: dimension mismatch: {:?} {:?} {:?}", stringify!($func), ($a.len(),), stringify!($op), diff --git a/examples/staging/macros/overload/overload.rs b/examples/staging/macros/overload/overload.rs index 8e07a25370..12392b1e8f 100644 --- a/examples/staging/macros/overload/overload.rs +++ b/examples/staging/macros/overload/overload.rs @@ -2,15 +2,15 @@ macro_rules! test { // the arguments don't need to be separated by a comma // any template can be used - println!("{} and {} is {}", ($left:expr; and $right:expr) => ( + println!("{:?} and {:?} is {:?}", stringify!($left), stringify!($right), $left && $right) ); // ^ each arm must be ended with a semicolon - println!("{} or {} is {}", ($left:expr; or $right:expr) => ( + println!("{:?} or {:?} is {:?}", stringify!($left), stringify!($right), $left || $right) From 4e4c48d7f2903dbf15bff2525ce3fa4025a4ef64 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 12 Jan 2015 22:09:48 -0500 Subject: [PATCH 0055/1122] Macros: test from playpen to code --- examples/staging/macros/dry/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/staging/macros/dry/input.md b/examples/staging/macros/dry/input.md index 01ea8e98b9..3ee64e9710 100644 --- a/examples/staging/macros/dry/input.md +++ b/examples/staging/macros/dry/input.md @@ -2,7 +2,7 @@ Macros allow writing DRY code, by factoring out the common parts of functions and/or test suites. Here is an example that implements and tests the `+=`, `*=` and `-=` operators on `Vec`. -{dry.play} +{dry.rs} ``` $ rustc --test dry.rs && ./dry From 3bc016ca772ab0f8beed707f760cdbd5f17a2b42 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 12 Jan 2015 22:14:29 -0500 Subject: [PATCH 0056/1122] Macros: add list of designators --- examples/staging/macros/designators/input.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/staging/macros/designators/input.md b/examples/staging/macros/designators/input.md index be5ad57116..9e64a10745 100644 --- a/examples/staging/macros/designators/input.md +++ b/examples/staging/macros/designators/input.md @@ -2,3 +2,15 @@ The arguments of a macro are prefixed by a dollar sign `$` and type annotated with a *designator*: {designators.play} + +This is a list of all the designators: + +* `block` +* `expr` is used for expressions +* `ident` is used for variable/function names +* `item` +* `pat` (*pattern*) +* `path` +* `stmt` (*statement*) +* `tt` (*token tree*) +* `ty` (*type*) From ac186cb43d8fc8e9c308b52f1b53742565d2ebc6 Mon Sep 17 00:00:00 2001 From: Max Brosnahan Date: Sun, 11 Jan 2015 00:34:12 +1300 Subject: [PATCH 0057/1122] Fix executed code output replacement --- src/markdown.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/markdown.rs b/src/markdown.rs index d33cd1d002..231cf39171 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -96,11 +96,12 @@ impl<'a, 'b> Markdown<'a, 'b> { match r.captures(line) { None => {}, Some(captures) => { - let src = captures.at(1); - let input = format!("{{{:?}.out}}", src); - let s = try!(file::run(prefix, id, src.unwrap())); + let src = captures.at(1).unwrap(); + let input = format!("{{{}.out}}", src); + let s = try!(file::run(prefix, id, src)); + let s = format!("``` \n\ - $ rustc {0:?}.rs && ./{0:?}\n{1:?}\n\ + $ rustc {0}.rs && ./{0}\n{1}\n\ ```", src, s); From e25baeb31f82ce08bd7f491a94d2d17354b90450 Mon Sep 17 00:00:00 2001 From: Justin Hamilton Date: Tue, 13 Jan 2015 09:59:30 -0800 Subject: [PATCH 0058/1122] Updating borrow/borrow: adding box_syntax feature, changing int to isize --- examples/borrow/borrow.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/borrow/borrow.rs b/examples/borrow/borrow.rs index 57bbcb8531..03264bf9f7 100644 --- a/examples/borrow/borrow.rs +++ b/examples/borrow/borrow.rs @@ -1,10 +1,11 @@ +#![feature(box_syntax)] // This function takes ownership of the box -fn eat_box(boxed_int: Box) { +fn eat_box(boxed_int: Box) { println!("destroying box that contains {}", boxed_int); } // This function borrows the box -fn peep_inside_box(borrowed_box: &Box) { +fn peep_inside_box(borrowed_box: &Box) { println!("This box contains {}", borrowed_box); } @@ -20,7 +21,7 @@ fn main() { { // Take a reference to the data contained inside the box - let _ref_to_int: &int = &*boxed_int; + let _ref_to_int: &isize = &*boxed_int; // Error! Can't destroy boxed_int, while the inner value has been // borrowed From 9d3ddd21c44e0488ea0e40fcd5ef280ed7098949 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Tue, 13 Jan 2015 12:43:33 -0800 Subject: [PATCH 0059/1122] Stop attempting to be clever in iter --- examples/iter/iter.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index bcd532c287..6027abe34b 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -13,10 +13,12 @@ impl Iterator for Fibonacci { // over, otherwise the next value is returned wrapped in 'Some' fn next(&mut self) -> Option { let new_next = self.curr + self.next; - let new_curr = mem::replace(&mut self.next, new_next); + + self.curr = self.next; + self.next = new_next; // 'Some' is always returned, this is an infinite value generator - Some(mem::replace(&mut self.curr, new_curr)) + Some(self.curr) } } From a9a16486c827df068e070e961d014ce6a1d74eb4 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Tue, 13 Jan 2015 12:48:37 -0800 Subject: [PATCH 0060/1122] Add small explanation for unit structs --- examples/structs/input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/structs/input.md b/examples/structs/input.md index 10190d6d08..6a3e438ff0 100644 --- a/examples/structs/input.md +++ b/examples/structs/input.md @@ -2,9 +2,9 @@ There are three types of structures ("structs") that can be created using the `struct` keyword: * Tuple structs, which are, basically, named tuples. -* The classic [C structs][1] -* Unit structs, which are field-less structs. +* The classic [C structs][c_struct] +* Unit structs, which are field-less structs, useful for generics {structs.play} -[1]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[c_struct]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) From cf1e0c89c2df0804b84cc64faea9edec0fc7ae95 Mon Sep 17 00:00:00 2001 From: Sanjiv Jha Date: Wed, 14 Jan 2015 02:26:05 +0530 Subject: [PATCH 0061/1122] fix the link in README.md update.rs replaced by main.rs but link in README.md still point to update.rs which not valid for current master. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64d7bc4beb..46afc924d9 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ We use these tools to generate the static site: works [here][gitbook-format]). Before running `gitbook`, we do a preprocessing step using -[src/update.rs][update-rs]. +[src/main.rs][main-rs]. This preprocessing has two steps: From 5bcf0bff85ef385ab4e3a1b56da0d65a3d87beaa Mon Sep 17 00:00:00 2001 From: Sanjiv Jha Date: Wed, 14 Jan 2015 02:30:45 +0530 Subject: [PATCH 0062/1122] updated link of update.rs to main.rs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46afc924d9..3442b09f57 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ See LICENSE-APACHE and LICENSE-MIT for more details. [rust-lang]: http://www.rust-lang.org/ [gitbook]: http://www.gitbook.io [gitbook-dir]: https://github.com/GitbookIO/gitbook#book-format -[update-rs]: src/update.rs +[main-rs]: src/main.rs [structure]: examples/structure.json [hello-folder]: examples/hello [hello-rs]: examples/hello/hello.rs From 6df740429a50953ca65f082fbce06a07e0640224 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Tue, 13 Jan 2015 17:22:12 -0800 Subject: [PATCH 0063/1122] Better grammar --- examples/structs/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/structs/input.md b/examples/structs/input.md index 6a3e438ff0..c77eae53e8 100644 --- a/examples/structs/input.md +++ b/examples/structs/input.md @@ -3,7 +3,7 @@ There are three types of structures ("structs") that can be created using the * Tuple structs, which are, basically, named tuples. * The classic [C structs][c_struct] -* Unit structs, which are field-less structs, useful for generics +* Unit structs, which are field-less, are useful for generics. {structs.play} From e1f94d5825b8e75b7ab01fd52b7da339d6f14a7b Mon Sep 17 00:00:00 2001 From: Justin Hamilton Date: Tue, 13 Jan 2015 18:49:00 -0800 Subject: [PATCH 0064/1122] Updating borrow/borrow: removing box_syntax feature, changing isize to i32 --- examples/borrow/borrow.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/borrow/borrow.rs b/examples/borrow/borrow.rs index 03264bf9f7..92041d59ab 100644 --- a/examples/borrow/borrow.rs +++ b/examples/borrow/borrow.rs @@ -1,17 +1,16 @@ -#![feature(box_syntax)] // This function takes ownership of the box -fn eat_box(boxed_int: Box) { +fn eat_box(boxed_int: Box) { println!("destroying box that contains {}", boxed_int); } // This function borrows the box -fn peep_inside_box(borrowed_box: &Box) { +fn peep_inside_box(borrowed_box: &Box) { println!("This box contains {}", borrowed_box); } fn main() { // A boxed integer - let boxed_int = box 5; + let boxed_int = Box::new(5); // Borrow the box, ownership is not taken peep_inside_box(&boxed_int); @@ -21,7 +20,7 @@ fn main() { { // Take a reference to the data contained inside the box - let _ref_to_int: &isize = &*boxed_int; + let _ref_to_int: &i32 = &*boxed_int; // Error! Can't destroy boxed_int, while the inner value has been // borrowed From f7cfeaaf234b89b02078f44bb16f9e5db90a27fe Mon Sep 17 00:00:00 2001 From: Naveen Date: Wed, 14 Jan 2015 17:08:10 -0500 Subject: [PATCH 0065/1122] Update print.rs Fixed the warning "`i` suffix on integers is deprecated; use `is` or one of the fixed-sized suffixes" by using `is` suffix. --- examples/print/print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index 49cb454f57..018b89ce7a 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -3,7 +3,7 @@ fn main() { print!("January has "); // `{}` are placeholders for arguments that will be stringified - println!("{} days", 31i); + println!("{} days", 31is); // The `i` suffix indicates the compiler that this literal has type: signed // pointer size integer, see next chapter for more details From 0bcc016bc6c9c4b2f5d33a31addc060556e9842a Mon Sep 17 00:00:00 2001 From: Naveen Date: Wed, 14 Jan 2015 18:11:45 -0500 Subject: [PATCH 0066/1122] Update print.rs Removed the suffix completely based comment. --- examples/print/print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index 018b89ce7a..b33d7c3b6d 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -3,7 +3,7 @@ fn main() { print!("January has "); // `{}` are placeholders for arguments that will be stringified - println!("{} days", 31is); + println!("{} days", 31); // The `i` suffix indicates the compiler that this literal has type: signed // pointer size integer, see next chapter for more details From 8b6ccae4e205aba7c3589dce3c6de4092a965d8f Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Thu, 15 Jan 2015 13:23:05 -0800 Subject: [PATCH 0067/1122] Various README fixes - Fix capitalization of Rust, Rust by Example, GitBook, and Markdown. - Fix link to GitBook output formats. - Other miscellaneous changes. --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3442b09f57..e6f264b9f4 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ ## What's this? -This is the source code of the -[Rust by example][website] website! +This is the source code of the [Rust by Example][website] website! ## How to contribute @@ -14,11 +13,11 @@ See [CONTRIBUTING.md][how-to-contribute]. First, make certain you install `nodejs` on Debian based distributions, or `node` on non-Debian distros. After installation, if you use a Debian based -distro (i.e. Ubuntu), run +distro (i.e. Ubuntu), run: sudo ln -s /usr/bin/nodejs /usr/bin/node -Then run +Then run: ``` make all @@ -33,9 +32,9 @@ View the results with `make serve`. We use these tools to generate the static site: * [Rust][rust-lang] \o/ -* [gitbook][gitbook] +* [GitBook][gitbook] -`gitbook` will generate the site from markdown files (see details about how it +`gitbook` will generate the site from Markdown files (see details about how it works [here][gitbook-format]). Before running `gitbook`, we do a preprocessing step using @@ -67,12 +66,12 @@ lives under the `variable` example. ### Processing `input.md` -Instead of including the rust code directly in `input.md`, the code lives in -separate source files; and the preprocessing step will insert the source code -in the markdown file. +Instead of including the Rust code directly in `input.md`, the code lives in +separate source files; the preprocessing step will insert the source code +into the Markdown file. For example, to insert the source code of the `hello.rs` file, the following -syntax is used in the markdown file: +syntax is used in the Markdown file: * `{hello.play}` expands the source code embedded in a live code editor * `{hello.rs}` expands to static/plain source code. @@ -88,7 +87,7 @@ The Makefile provides the following recipes: ## License -Rust by example is dual licensed under the Apache 2.0 license and the MIT +Rust by Example is dual-licensed under the Apache 2.0 license and the MIT license. See LICENSE-APACHE and LICENSE-MIT for more details. @@ -99,7 +98,7 @@ See LICENSE-APACHE and LICENSE-MIT for more details. [how-to-contribute]: CONTRIBUTING.md [rust-lang]: http://www.rust-lang.org/ [gitbook]: http://www.gitbook.io -[gitbook-dir]: https://github.com/GitbookIO/gitbook#book-format +[gitbook-format]: https://github.com/GitbookIO/gitbook#book-format [main-rs]: src/main.rs [structure]: examples/structure.json [hello-folder]: examples/hello From 87ae95a068d41d9ad96556243117e3cb305df004 Mon Sep 17 00:00:00 2001 From: Aidan Hobson Sayers Date: Thu, 15 Jan 2015 23:03:38 +0000 Subject: [PATCH 0068/1122] generics/impl: clarify that generics don't depend on a null struct --- examples/generics/impl/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 5147a56408..4606297574 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -2,12 +2,12 @@ Implementations can also be made generic. Generally `impl` is followed by the type `` although it is not a strict requirement. ```rust -struct T; // A null struct +struct S; // A null struct struct GenericTup(T,); // impl of GenericTup we specifically specialize: impl GenericTup {} // Specialize to `f32` -impl GenericTup {} // Specialize to `T` defined above +impl GenericTup {} // Specialize to `S` defined above // `` Must precede the type to remain generic impl GenericTup {} From 75422a0a5ff2ee3d6b663ad10ad44486a654ef90 Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Thu, 15 Jan 2015 15:29:27 -0800 Subject: [PATCH 0069/1122] Add margin to bottom of interactive code blocks --- node_modules/gitbook-plugin-rust-playpen/book/editor.css | 1 + 1 file changed, 1 insertion(+) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index f3bcdd9096..2d2806bcf2 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -7,6 +7,7 @@ border-radius: 4px; background-color: #FDFDFD; border: 1px solid #CCC; + margin-bottom: 16px; } #editor { From 577985f33209ea4cdd7d75d0e6227b5dac64533b Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Fri, 16 Jan 2015 00:03:54 -0800 Subject: [PATCH 0070/1122] Rename int/uint to isize/usize in type/input.md Also, isize and usize are technically the size of a pointer, not a machine word --- examples/type/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/type/input.md b/examples/type/input.md index 7920fb803f..dc62a4f284 100644 --- a/examples/type/input.md +++ b/examples/type/input.md @@ -7,8 +7,8 @@ annotation burden. This is a summary of the primitive types in Rust: -* signed integers: `i8`, `i16`, `i32`, `i64` and `int` (machine word size) -* unsigned integers: `u8`, `u16`, `u32`, `u64` and `uint` (machine word size) +* signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) +* unsigned integers: `u8`, `u16`, `u32`, `u64` and `usize` (pointer size) * floating point: `f32`, `f64` * `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) * `bool` either `true` or `false` From 528bac023e4114f923f78ab12ab7a2864bce8763 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 17 Jan 2015 23:19:45 -0500 Subject: [PATCH 0071/1122] Remove unused use --- examples/iter/iter.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index 6027abe34b..f9ad67812c 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -1,5 +1,3 @@ -use std::mem; - struct Fibonacci { curr: u32, next: u32, From 2d766ce523bbcb98b7a9533cdacdcb21f7de6b4c Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 18 Jan 2015 02:55:12 -0500 Subject: [PATCH 0072/1122] `int` -> `isize`, `uint` -> `usize` --- examples/type/alias/alias.rs | 8 ++++---- examples/type/alias/input.md | 2 +- examples/type/literals/input.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/type/alias/alias.rs b/examples/type/alias/alias.rs index 3d5bd0fb9f..765a5ec95f 100644 --- a/examples/type/alias/alias.rs +++ b/examples/type/alias/alias.rs @@ -4,13 +4,13 @@ type Inch = u64; // Use an attribute to silence warning #[allow(non_camel_case_types)] -type uint64_t = u64; +type u64_t = u64; // TODO ^ Try removing the attribute fn main() { - // `NanoSecond` = `Inch` = `uint64_t` = `u64` - let nanoseconds: NanoSecond = 5 as uint64_t; - let inches: Inch = 2 as uint64_t; + // `NanoSecond` = `Inch` = `u64_t` = `u64` + let nanoseconds: NanoSecond = 5 as u64_t; + let inches: Inch = 2 as u64_t; // Note that type aliases *don't* provide any extra type safety, because // aliases are *not* new types diff --git a/examples/type/alias/input.md b/examples/type/alias/input.md index c9e16c7ae8..6492b9f033 100644 --- a/examples/type/alias/input.md +++ b/examples/type/alias/input.md @@ -1,6 +1,6 @@ The `type` statement can be used to give a new name to an existing type. Types must have `CamelCase` names, or the compiler will raise a warning. The -exception to this rule are the primitive types: `uint`, `f32`, etc. +exception to this rule are the primitive types: `usize`, `f32`, etc. {alias.play} diff --git a/examples/type/literals/input.md b/examples/type/literals/input.md index b971dbf684..44e35f8aae 100644 --- a/examples/type/literals/input.md +++ b/examples/type/literals/input.md @@ -1,5 +1,5 @@ Numeric literals can be type annotated by adding the type as a suffix, with the -exception of `uint` that uses the `u` suffix and `int` that uses the `i` +exception of `usize` that uses the `us` suffix and `isize` that uses the `is` suffix. The type of unsuffixed literals will depend on how they are used. If no From e6f5e6f75eb51b1110c392de8fef840ad43f7e0b Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 19 Jan 2015 19:07:01 -0500 Subject: [PATCH 0073/1122] Link back to github source code page --- examples/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 4b23e507b8..aa81e06137 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,7 +4,8 @@ type safety, memory safety, concurrency and performance. This book is a collection of bitesize examples that illustrate various rustic -concepts and the Rust distribution libraries. +concepts and the Rust distribution libraries. The source code is hosted +[here][home]. Be sure to have rust [installed][install] and the [docs][std] at hand, let's @@ -17,3 +18,4 @@ versions like 0.10, be sure to use a nightly version! [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html [std]: http://doc.rust-lang.org/std/ +[home]: https://github.com/rust-lang/rust-by-example From c4490dab41c24f58eb6ce794ce4c3381761f932f Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 19 Jan 2015 19:13:49 -0500 Subject: [PATCH 0074/1122] Remove json chapters because the examples are missing --- examples/structure.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/structure.json b/examples/structure.json index 6d556bc6f3..62eb88ab12 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -126,11 +126,6 @@ { "id": "simd", "title": "SIMD", "children": null }, { "id": "test", "title": "Testing", "children": null }, { "id": "unsafe", "title": "Unsafe operations", "children": null }, - { "id": "json", "title": "JSON parsing", "children": [ - { "id": "json-enum", "title": "`Json`", "children": null }, - { "id": "decodable", "title": "`Decodable`", "children": null }, - { "id": "encodable", "title": "`Encodable`", "children": null } - ] }, { "id": "fmt", "title": "Formatting", "children": null }, { "id": "hash", "title": "HashMap", "children": [ { "id": "alt-key-types", "title": "Alternate/custom key types", "children": null}, From 3a3c8fd467879d84e19e67fbf6219b2ea4f0be66 Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Mon, 19 Jan 2015 21:37:05 -0800 Subject: [PATCH 0075/1122] Minor grammatical fixes in README.md --- examples/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/README.md b/examples/README.md index aa81e06137..1b656bf45c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,13 +7,12 @@ This book is a collection of bitesize examples that illustrate various rustic concepts and the Rust distribution libraries. The source code is hosted [here][home]. -Be sure to have rust [installed][install] and the -[docs][std] at hand, let's -start! +Be sure to have Rust [installed][install] and the [docs][std] at hand, +and let's start! *Note*: This book will follow the nightly version of Rust until we reach -version 1.0, it's highly possible that some examples won't work with snapshot -versions like 0.10, be sure to use a nightly version! +version 1.0; it's highly possible that some examples won't work with snapshot +versions like 0.10, so be sure to use a nightly version! [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html From 96c557514bbf59c51ad6374c1b2fdac1cd0c0a60 Mon Sep 17 00:00:00 2001 From: David Shepherd Date: Wed, 21 Jan 2015 16:10:41 +0000 Subject: [PATCH 0076/1122] Fix warning about uint: use u32 instead --- examples/borrow/mut/mut.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/borrow/mut/mut.rs b/examples/borrow/mut/mut.rs index 3c085a7f27..e96eb52daa 100644 --- a/examples/borrow/mut/mut.rs +++ b/examples/borrow/mut/mut.rs @@ -4,7 +4,7 @@ struct Book { // `&'static str` is a reference to a string allocated in read only memory author: &'static str, title: &'static str, - year: uint, + year: u32, } // This function takes a reference to a book From 09574f6556bac7e63d5939c73e67742c07245830 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 23 Jan 2015 11:30:14 -0500 Subject: [PATCH 0077/1122] Fix the build --- examples/array/array.rs | 4 ++-- examples/staging/ffi/ffi.rs | 2 +- examples/staging/ffi/safe.rs | 2 +- examples/staging/fmt/show.rs | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/array/array.rs b/examples/array/array.rs index 01fb6ce1ca..e8a1e1a300 100644 --- a/examples/array/array.rs +++ b/examples/array/array.rs @@ -9,7 +9,7 @@ fn analyze_slice(slice: &[i32]) { fn main() { // Fixed-size array (type signature is superfluous) let xs: [i32; 5] = [1, 2, 3, 4, 5]; - + // All elements can be initialized to the same value let ys: [i32; 500] = [0; 500]; @@ -29,7 +29,7 @@ fn main() { // Slices can point to a section of an array println!("borrow a section of the array as a slice"); - analyze_slice(ys.slice(1, 4)); + analyze_slice(&ys[1 .. 4]); // Out of bound indexing yields a task failure println!("{}", xs[5]); diff --git a/examples/staging/ffi/ffi.rs b/examples/staging/ffi/ffi.rs index 767813ead3..8adfb6e12e 100644 --- a/examples/staging/ffi/ffi.rs +++ b/examples/staging/ffi/ffi.rs @@ -28,7 +28,7 @@ struct Complex { im: f32, } -impl fmt::Show for Complex { +impl fmt::Debug for Complex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.im < 0. { write!(f, "{}-{}i", self.re, -self.im) diff --git a/examples/staging/ffi/safe.rs b/examples/staging/ffi/safe.rs index 02005d6cd6..4fd258634c 100644 --- a/examples/staging/ffi/safe.rs +++ b/examples/staging/ffi/safe.rs @@ -25,7 +25,7 @@ struct Complex { im: f32, } -impl fmt::Show for Complex { +impl fmt::Debug for Complex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.im < 0. { write!(f, "{}-{}i", self.re, -self.im) diff --git a/examples/staging/fmt/show.rs b/examples/staging/fmt/show.rs index da6d1cf241..6b06cab457 100644 --- a/examples/staging/fmt/show.rs +++ b/examples/staging/fmt/show.rs @@ -1,4 +1,4 @@ -use std::fmt::{self, Formatter, Show}; +use std::fmt::{self, Formatter, Display}; // For .abs() use std::num::Float; @@ -10,7 +10,7 @@ struct City { lon: f32, } -impl Show for City { +impl Display for City { // `f` is a buffer, this method must write the formatted string into it fn fmt(&self, f: &mut Formatter) -> fmt::Result { let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; @@ -29,7 +29,7 @@ fn main() { City { name: "Oslo", lat: 59.95, lon: 10.75 }, City { name: "Vancouver", lat: 49.25, lon: -123.1 }, ].iter() { - println!("{:?}", city); + println!("{}", *city); } } From fd9f6cdcea0a09f120a01912eec45f51f5a1ef1d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 23 Jan 2015 11:39:54 -0500 Subject: [PATCH 0078/1122] Update rustc-serialize to fix make --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 204d62fd0d..d16c5564d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" From 4264236bb76521ba728d8ec62ee0c35ecbc257af Mon Sep 17 00:00:00 2001 From: Naveen Date: Sat, 24 Jan 2015 10:46:51 -0500 Subject: [PATCH 0079/1122] Updated print.rs to remove the "i" suffix. The "i" suffix has been replaced by "is" and is not required now for this change. This removes the warning. --- examples/print/print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index b33d7c3b6d..acfc69d3bb 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -17,7 +17,7 @@ fn main() { verb="jumps"); // Special formatting can be specified in the placeholder after a `:` - println!("{} of {:b} people know binary, the other half don't", 1i, 2i); + println!("{} of {:b} people know binary, the other half don't", 1, 2); // Error! You are missing an argument println!("My name is {0}, {1} {0}", "Bond"); From 736666f10b6f35c156a1de2181b54166350698d6 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 13:35:50 +0100 Subject: [PATCH 0080/1122] the `i` suffix on integers is deprecated --- examples/print/print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index b33d7c3b6d..acfc69d3bb 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -17,7 +17,7 @@ fn main() { verb="jumps"); // Special formatting can be specified in the placeholder after a `:` - println!("{} of {:b} people know binary, the other half don't", 1i, 2i); + println!("{} of {:b} people know binary, the other half don't", 1, 2); // Error! You are missing an argument println!("My name is {0}, {1} {0}", "Bond"); From f3e4a891dac4b1c38a2c82cd47593b62602dd83e Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 14:53:24 +0100 Subject: [PATCH 0081/1122] i suffix --- examples/variables/mut/mut.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/variables/mut/mut.rs b/examples/variables/mut/mut.rs index 023aa69fb0..d2a8470a74 100644 --- a/examples/variables/mut/mut.rs +++ b/examples/variables/mut/mut.rs @@ -1,6 +1,6 @@ fn main() { - let _immutable_variable = 1i; - let mut mutable_variable = 1i; + let _immutable_variable = 1; + let mut mutable_variable = 1; println!("Before mutation: {}", mutable_variable); From 0f6f0a723997a9680b63276ec7506a01608e0bc1 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 17:42:58 +0100 Subject: [PATCH 0082/1122] i suffix --- examples/variables/scope/scope.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/variables/scope/scope.rs b/examples/variables/scope/scope.rs index 7cb1624380..409be705dc 100644 --- a/examples/variables/scope/scope.rs +++ b/examples/variables/scope/scope.rs @@ -1,11 +1,11 @@ fn main() { // This variable lives in the main function - let long_lived_variable = 1i; + let long_lived_variable = 1; // This is a block, and has a smaller scope than the main function { // This variable only exists in this block - let short_lived_variable = 2i; + let short_lived_variable = 2; println!("inner short: {}", short_lived_variable); From 0dc29efb0f0cefd37bba48040b714ecbc2e170b1 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 17:46:18 +0100 Subject: [PATCH 0083/1122] i suffix --- examples/variables/declare/declare.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/variables/declare/declare.rs b/examples/variables/declare/declare.rs index ec54714807..e2e0c06537 100644 --- a/examples/variables/declare/declare.rs +++ b/examples/variables/declare/declare.rs @@ -3,7 +3,7 @@ fn main() { let a_variable; { - let x = 2i; + let x = 2; // Initialize the variable a_variable = x * x; @@ -17,7 +17,7 @@ fn main() { println!("another variable: {}", another_variable); // FIXME ^ Comment out this line - another_variable = 1i; + another_variable = 1; println!("another variable: {}", another_variable); } From 3112fd846b4036e2ff309ec1c1544d7ce9c10000 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 17:50:25 +0100 Subject: [PATCH 0084/1122] i suffix -> i32 --- examples/type/type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/type/type.rs b/examples/type/type.rs index deda1c2a3c..4073141828 100644 --- a/examples/type/type.rs +++ b/examples/type/type.rs @@ -3,7 +3,7 @@ fn main() { let a_float: f64 = 1.0; // This variable is an `int` - let mut an_integer = 5i; + let mut an_integer = 5i32; // Error! The type of a variable can't be changed an_integer = true; From f7c30378ea9c0bf521272702668dc70c23fca1b1 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 19:05:03 +0100 Subject: [PATCH 0085/1122] replace the range function with the range syntax --- examples/for/for.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/for/for.rs b/examples/for/for.rs index c2ac3d49b0..918f846472 100644 --- a/examples/for/for.rs +++ b/examples/for/for.rs @@ -1,6 +1,6 @@ fn main() { // `n` will take the values: 1, 2, ..., 100 in each iteration - for n in range(1u32, 101) { + for n in 1u32..101 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { From 5f786546d911629240912b7e042e0467af51c66e Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Sun, 25 Jan 2015 19:09:13 +0100 Subject: [PATCH 0086/1122] replace range function with range notation --- examples/for/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/for/input.md b/examples/for/input.md index 13662c44c0..a3e647dae5 100644 --- a/examples/for/input.md +++ b/examples/for/input.md @@ -1,6 +1,6 @@ The `for in` construct can be used to iterate an `Iterator`, a lazy value -generator (more details later). One of the most common iterators is the `range` -function. `range(a, b)` will yield values from `a` (inclusive) to `b` +generator (more details later). One of the easiest way to create an iterator +is to use the range notation. `a..b` will yield values from `a` (inclusive) to `b` (exclusive) in steps of one. Let's write fizzbuzz using `for` instead of `while`. From d92c355a153d01717a3b013612619494959a222e Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Tue, 27 Jan 2015 00:23:14 -0800 Subject: [PATCH 0087/1122] Fix #419 (check all whitelisted examples) I didn't do anything about `print.rs`, this is a pure bugfix --- Makefile | 30 +++++++++++++++--------------- examples/borrow/freeze/freeze.rs | 2 +- examples/constants/constants.rs | 4 ++-- examples/lifetime/borrow/borrow.rs | 12 ++++++------ examples/vec/vec.rs | 12 ++++++------ 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 26deb55f47..c77e28ae9c 100644 --- a/Makefile +++ b/Makefile @@ -4,21 +4,21 @@ STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -A unstable RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ - examples/borrow/borrow.rs \ - examples/borrow/freeze/freeze.rs \ - examples/borrow/mut/mut.rs \ - examples/bounds/bounds.rs \ - examples/constants/constants.rs \ - examples/crates/link/executable.rs \ - examples/lifetime/borrow/borrow.rs \ - examples/mod/mod.rs \ - examples/print/print.rs \ - examples/type/cast/cast.rs \ - examples/type/type.rs \ - examples/variables/declare/declare.rs \ - examples/variables/mut/mut.rs \ - examples/variables/scope/scope.rs \ - examples/vec/vec.rs \ + examples/borrow/borrow.rs \ + examples/borrow/freeze/freeze.rs \ + examples/borrow/mut/mut.rs \ + examples/bounds/bounds.rs \ + examples/constants/constants.rs \ + examples/crates/link/executable.rs \ + examples/lifetime/borrow/borrow.rs \ + examples/mod/mod.rs \ + examples/print/print.rs \ + examples/type/cast/cast.rs \ + examples/type/type.rs \ + examples/variables/scope/scope.rs \ + examples/variables/mut/mut.rs \ + examples/variables/declare/declare.rs \ + examples/vec/vec.rs srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) diff --git a/examples/borrow/freeze/freeze.rs b/examples/borrow/freeze/freeze.rs index 60a919c7fb..16a466d792 100644 --- a/examples/borrow/freeze/freeze.rs +++ b/examples/borrow/freeze/freeze.rs @@ -1,5 +1,5 @@ fn main() { - let mut _integer = 5i; + let mut _integer = 5i32; { // Borrow `integer` diff --git a/examples/constants/constants.rs b/examples/constants/constants.rs index 6db121c1dd..dc8717643b 100644 --- a/examples/constants/constants.rs +++ b/examples/constants/constants.rs @@ -1,7 +1,7 @@ static LANGUAGE: &'static str = "Rust"; -static THRESHOLD: int = 10; +static THRESHOLD: i32 = 10; -fn is_big(n: int) -> bool { +fn is_big(n: i32) -> bool { // Access constant in some function n > THRESHOLD } diff --git a/examples/lifetime/borrow/borrow.rs b/examples/lifetime/borrow/borrow.rs index 3e4d20a225..8e5f2cc869 100644 --- a/examples/lifetime/borrow/borrow.rs +++ b/examples/lifetime/borrow/borrow.rs @@ -1,17 +1,17 @@ // FIXME To see the "real" compiler error, change both `&'b` and `&'e` into `&` fn main() { // `'main` starts ────────────────────────────────────────────┐ - let stack_integer: int = 5; // `'a` starts ─────────────────────────┐ │ - let boxed_integer = box 4; // `'b` starts ────────────────────────┐ │ │ + let stack_integer: i32 = 5; // `'a` starts ─────────────────────────┐ │ + let boxed_integer = Box::new(4); // `'b` starts ──────────────────┐ │ │ // │ │ │ // This is a valid operation │ │ │ - let ref_to_box: &'b int = &*boxed_integer; // `'c` starts ──────┐ │ │ │ + let ref_to_box: &'b i32 = &*boxed_integer; // `'c` starts ──────┐ │ │ │ // │ │ │ │ // The compiler forbids this operation, because │ │ │ │ // `ref_to_another_box` would become a dangling pointer │ │ │ │ - let ref_to_another_box: &'e int = { // `'let` `'d` start ───┬─┐ │ │ │ │ - let another_boxed_integer = box 3; // `'e` starts ────┐ │ │ │ │ │ │ - // │ │ │ │ │ │ │ + let ref_to_another_box: &'e i32 = { // `'let` `'d` start ───┬─┐ │ │ │ │ + let another_boxed_integer = Box::new(3); // ──────────┐ │ │ │ │ │ │ + // ^ `e` starts │ │ │ │ │ │ │ &*another_boxed_integer // │ │ │ │ │ │ │ }; // `'e` `'let` end ────────────────────────────────────┴─┘ │ │ │ │ │ // │ │ │ │ │ diff --git a/examples/vec/vec.rs b/examples/vec/vec.rs index b960cbd134..3b6fe7c6fc 100644 --- a/examples/vec/vec.rs +++ b/examples/vec/vec.rs @@ -1,16 +1,16 @@ fn main() { // Iterators can be collected into vectors - let collected_iterator: Vec = range(0i, 10).collect(); - println!("Collected range(0, 10) into: {}", collected_iterator); + let collected_iterator: Vec = range(0, 10).collect(); + println!("Collected range(0, 10) into: {:?}", collected_iterator); // The `vec!` macro can be used to initialize a vector - let mut xs = vec![1i, 2, 3]; - println!("Initial vector: {}", xs); + let mut xs = vec![1i32, 2, 3]; + println!("Initial vector: {:?}", xs); // Insert new element at the end of the vector println!("Push 4 into the vector"); xs.push(4); - println!("Vector: {}", xs); + println!("Vector: {:?}", xs); // Error! Immutable vectors can't grow collected_iterator.push(0); @@ -23,7 +23,7 @@ fn main() { println!("Second element: {}", xs[1]); // `pop` removes the last element from the vector and returns it - println!("Pop last element: {}", xs.pop()); + println!("Pop last element: {:?}", xs.pop()); // Out of bounds indexing yields a task failure println!("Fourth element: {}", xs[3]); From 88199f8de53fcc319fb28b7659552afd6a1d1bb2 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 28 Jan 2015 19:23:25 -0500 Subject: [PATCH 0088/1122] Update to https --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 0eecaba017..77f2e809d1 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -165,7 +165,7 @@ function runProgram(program, callback) { }); // console.log("Sending", data); - req.open('POST', "http://play.rust-lang.org/evaluate.json", true); + req.open('POST', "https://play.rust-lang.org/evaluate.json", true); req.onload = function(e) { if (req.readyState === 4 && req.status === 200) { var result = JSON.parse(req.response).result; From c88222cb1d201112d8e2cc08e5bca8ca7c5d3cdf Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 28 Jan 2015 21:20:46 -0500 Subject: [PATCH 0089/1122] io to old_io --- examples/file/create/create.rs | 2 +- examples/file/open/open.rs | 2 +- examples/fs/fs.rs | 6 +++--- examples/path/path.rs | 2 +- examples/process/pipe/pipe.rs | 2 +- examples/process/process.rs | 2 +- examples/process/wait/wait.rs | 2 +- examples/sockets/client.rs | 2 +- examples/sockets/server.rs | 8 ++++---- examples/staging/arg/getopts/echo.rs | 4 ++-- examples/timers/timers.rs | 4 ++-- src/file.rs | 8 ++++---- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 09d2d1088e..473551946a 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,4 +1,4 @@ -use std::io::File; +use std::old_io::File; static LOREM_IPSUM: &'static str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index f857e74c82..cd9dcc620e 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,4 +1,4 @@ -use std::io::File; +use std::old_io::File; fn main() { // Create a path to the desired file diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 61b213371a..92468f14b7 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -1,6 +1,6 @@ -use std::io::fs; -use std::io::fs::PathExtensions; -use std::io::{File, IoResult, USER_RWX}; +use std::old_io::fs; +use std::old_io::fs::PathExtensions; +use std::old_io::{File, IoResult, USER_RWX}; // A simple implementation of `% cat path` fn cat(path: &Path) -> IoResult { diff --git a/examples/path/path.rs b/examples/path/path.rs index 0e5ffa67d5..eac18da8e0 100644 --- a/examples/path/path.rs +++ b/examples/path/path.rs @@ -1,4 +1,4 @@ -use std::io::fs::PathExtensions; +use std::old_io::fs::PathExtensions; fn main() { // Create a `Path` from an `&'static str` diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index c2744bf5e8..565d292acc 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,4 +1,4 @@ -use std::io::process::Command; +use std::old_io::process::Command; static PANGRAM: &'static str = "the quick brown fox jumped over the lazy dog\n"; diff --git a/examples/process/process.rs b/examples/process/process.rs index 34e0a130f0..7d80c2a7fe 100644 --- a/examples/process/process.rs +++ b/examples/process/process.rs @@ -1,4 +1,4 @@ -use std::io::process::{Command,ProcessOutput}; +use std::old_io::process::{Command,ProcessOutput}; fn main() { // Initial command `rustc` diff --git a/examples/process/wait/wait.rs b/examples/process/wait/wait.rs index 714cc1fd06..296953e3ff 100644 --- a/examples/process/wait/wait.rs +++ b/examples/process/wait/wait.rs @@ -1,4 +1,4 @@ -use std::io::process::Command; +use std::old_io::process::Command; fn main() { let _process = Command::new("sleep").arg("5").spawn(); diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index a1bd4271a2..a5c6ae4baa 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -1,5 +1,5 @@ use common::SOCKET_PATH; -use std::io::net::pipe::UnixStream; +use std::old_io::net::pipe::UnixStream; use std::os; mod common; diff --git a/examples/sockets/server.rs b/examples/sockets/server.rs index 6107e00133..0dcc1b3f77 100644 --- a/examples/sockets/server.rs +++ b/examples/sockets/server.rs @@ -1,8 +1,8 @@ use common::SOCKET_PATH; -use std::io::fs; -use std::io::fs::PathExtensions; -use std::io::net::pipe::UnixListener; -use std::io::{Acceptor,Listener}; +use std::old_io::fs; +use std::old_io::fs::PathExtensions; +use std::old_io::net::pipe::UnixListener; +use std::old_io::{Acceptor,Listener}; mod common; diff --git a/examples/staging/arg/getopts/echo.rs b/examples/staging/arg/getopts/echo.rs index f47a9eadb2..d8f44ad586 100644 --- a/examples/staging/arg/getopts/echo.rs +++ b/examples/staging/arg/getopts/echo.rs @@ -1,8 +1,8 @@ extern crate getopts; use std::os; -use std::io::{print, println}; -use std::io::stdio; +use std::old_io::{print, println}; +use std::old_io::stdio; static VERSION: &'static str = "1.0.0"; diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index d7587849a2..46560cfb47 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -1,5 +1,5 @@ -use std::io::Timer; -use std::io::timer; +use std::old_io::Timer; +use std::old_io::timer; use std::time::duration::Duration; use std::iter; use std::sync::mpsc; diff --git a/src/file.rs b/src/file.rs index d52300e8f2..ae97e84c42 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,7 +1,7 @@ -use std::io::USER_RWX; -use std::io::fs; -use std::io::process::{Command,ProcessOutput}; -use std::io::{File,Truncate,Write}; +use std::old_io::USER_RWX; +use std::old_io::fs; +use std::old_io::process::{Command,ProcessOutput}; +use std::old_io::{File,Truncate,Write}; use std::os; pub fn mkdir(path: &Path) { From deceb5e52c44e98bee7012b338796d25e9d679a4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 28 Jan 2015 21:21:16 -0500 Subject: [PATCH 0090/1122] Update cargo lock --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d16c5564d2..f6850b54eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" From c404273868f3043b566fd4adbe773fafeea8aaa9 Mon Sep 17 00:00:00 2001 From: ctjhoa Date: Thu, 29 Jan 2015 17:01:53 +0100 Subject: [PATCH 0091/1122] Fix missing io to old_io for mod --- examples/mod/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mod/mod.rs b/examples/mod/mod.rs index 849bbe9576..7cff97e3c1 100644 --- a/examples/mod/mod.rs +++ b/examples/mod/mod.rs @@ -26,7 +26,7 @@ fn main() { // The `println` function lives in the `stdio` module // The `stdio` module lives in the `io` module // And the `io` module lives in the `std` crate - std::io::stdio::println("Hello World!"); + std::old_io::stdio::println("Hello World!"); // Error! `my::function` is private my::function(); From a1d5c58d33eb9df176965b7dd682d2dbc1dbd60a Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 29 Jan 2015 13:25:44 -0500 Subject: [PATCH 0092/1122] Fix feature build errors --- Makefile | 2 +- src/main.rs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 26deb55f47..67f64fbc41 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated -QUIET = -A unused-variables -A dead-code -A unused-assignments -A unstable +QUIET = -A unused-variables -A dead-code -A unused-assignments RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/borrow/borrow.rs \ diff --git a/src/main.rs b/src/main.rs index 0e6b4b5399..096a6be44e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,13 @@ +#![feature(os)] +#![feature(io)] +#![feature(std_misc)] +#![feature(path)] +#![feature(core)] + #![deny(warnings)] #![feature(int_uint)] #![feature(plugin)] -#![allow(unstable)] - extern crate regex; extern crate "rustc-serialize" as rustc_serialize; From aaaf9e37dce2234e2cb9e6c8291fe17f95ed6d67 Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Thu, 29 Jan 2015 14:53:13 -0800 Subject: [PATCH 0093/1122] Miscellaneous grammatical fixes --- examples/expression/input.md | 6 +++--- examples/fn/input.md | 4 ++-- examples/for/input.md | 2 +- examples/hello/input.md | 2 +- examples/if-else/input.md | 4 ++-- examples/type/alias/input.md | 2 +- examples/type/literals/input.md | 4 ++-- examples/variables/declare/input.md | 4 ++-- examples/while/input.md | 4 +++- 9 files changed, 17 insertions(+), 15 deletions(-) diff --git a/examples/expression/input.md b/examples/expression/input.md index ca8971f997..5e4b0d8179 100644 --- a/examples/expression/input.md +++ b/examples/expression/input.md @@ -1,4 +1,4 @@ -In Rust, almost every statement is an expression, this means that the statement +In Rust, almost every statement is an expression, meaning that the statement returns a value. This may not always be desired, so the output can be suppressed by ending the expression with a semicolon `;`. @@ -6,8 +6,8 @@ Blocks are expressions too, so they can be used as [r-values][rvalue] in assignments. The last expression in the block will be assigned to the [l-value][lvalue]. -But, if the last expression of the block ends with a semicolon, the return -value will be `()`. +However, if the last expression of the block ends with a semicolon, the +return value will be `()`. {expression.play} diff --git a/examples/fn/input.md b/examples/fn/input.md index b2de5ac5a2..c8b9db6c69 100644 --- a/examples/fn/input.md +++ b/examples/fn/input.md @@ -1,11 +1,11 @@ Functions are declared using the `fn` keyword. Its arguments are type -annotated, just like variables; and, if the function returns a value, the +annotated, just like variables, and, if the function returns a value, the return type must be specified after an arrow `->`. The final expression in the function will be used as return value. Alternatively, the `return` statement can be used to return a value earlier from within the function, even from inside loops or ifs. -Let's rewrite fizzbuzz using functions! +Let's rewrite FizzBuzz using functions! {fn.play} diff --git a/examples/for/input.md b/examples/for/input.md index a3e647dae5..99db3aa52a 100644 --- a/examples/for/input.md +++ b/examples/for/input.md @@ -3,6 +3,6 @@ generator (more details later). One of the easiest way to create an iterator is to use the range notation. `a..b` will yield values from `a` (inclusive) to `b` (exclusive) in steps of one. -Let's write fizzbuzz using `for` instead of `while`. +Let's write FizzBuzz using `for` instead of `while`. {for.play} diff --git a/examples/hello/input.md b/examples/hello/input.md index 926ea7c897..d8de3d239e 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -5,7 +5,7 @@ This is the source code of the traditional Hello World program. `println!` is a *macro* (we'll cover them later) that prints text to the console. -A binary can be generated using the rust compiler: `rustc`. +A binary can be generated using the Rust compiler: `rustc`. ``` $ rustc hello.rs diff --git a/examples/if-else/input.md b/examples/if-else/input.md index 755ab1eb9f..d6cd71b335 100644 --- a/examples/if-else/input.md +++ b/examples/if-else/input.md @@ -1,6 +1,6 @@ Branching with if-else is similar to C. Unlike C, the boolean condition doesn't need to be surrounded by parentheses, and each condition is followed by a -block. If-else conditionals are expressions too; and, because of Rust type -safety, all the branches must return the same type. +block. If-else conditionals are expressions too, and, because of Rust's type +safety, all branches must return the same type. {if-else.play} diff --git a/examples/type/alias/input.md b/examples/type/alias/input.md index 6492b9f033..3647b0b79d 100644 --- a/examples/type/alias/input.md +++ b/examples/type/alias/input.md @@ -4,7 +4,7 @@ exception to this rule are the primitive types: `usize`, `f32`, etc. {alias.play} -The main use of aliases is to reduce typing, for example the +The main use of aliases is to reduce typing; for example the [`IoResult`][io-result] type is an alias for the `Result` type. diff --git a/examples/type/literals/input.md b/examples/type/literals/input.md index 44e35f8aae..7d725cacfe 100644 --- a/examples/type/literals/input.md +++ b/examples/type/literals/input.md @@ -13,9 +13,9 @@ yet, here's a brief explanation for the impatient readers: * `fun(&foo)` is used to pass an argument to a function *by reference*, rather than by value (`fun(foo)`). For more details see [borrowing][borrow]. * `std::mem::size_of_val` is a function, but called with its *full path*. Code - can be split in logical units called *modules*. In this case the + can be split in logical units called *modules*. In this case, the `size_of_val` function is defined in the `mem` module, and the `mem` module - is defined in the `std` *crate*. For more details see + is defined in the `std` *crate*. For more details, see [modules][mod] and [crates][crate]. [borrow]: /borrow.html diff --git a/examples/variables/declare/input.md b/examples/variables/declare/input.md index 2bad0e6677..01b6cd8ac5 100644 --- a/examples/variables/declare/input.md +++ b/examples/variables/declare/input.md @@ -1,5 +1,5 @@ -It's possible to declare variables first, and initialize them later. But, this -form is seldom used, as it may lead to the use of uninitialized variables. +It's possible to declare variables first, and initialize them later. However, +this form is seldom used, as it may lead to the use of uninitialized variables. {declare.play} diff --git a/examples/while/input.md b/examples/while/input.md index b7d0cf842e..b03738de6b 100644 --- a/examples/while/input.md +++ b/examples/while/input.md @@ -1,5 +1,7 @@ The `while` keyword can be used to loop until a condition is met. -Let's write the infamous fizzbuzz using a `while` loop. +Let's write the infamous [FizzBuzz][fizzbuzz] using a `while` loop. {while.play} + +[fizzbuzz]: http://en.wikipedia.org/wiki/Fizz_buzz From e29dc2a5195ddb27b589e62554b6f7cf077de22c Mon Sep 17 00:00:00 2001 From: michaelmcgirr Date: Fri, 30 Jan 2015 15:00:36 -0800 Subject: [PATCH 0094/1122] Fixed a typo. The fizzbuzz_to function is corrected to now use Rust's new a..b range syntax --- examples/fn/fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/fn.rs b/examples/fn/fn.rs index ff35d81e52..9a5cd92af6 100644 --- a/examples/fn/fn.rs +++ b/examples/fn/fn.rs @@ -31,7 +31,7 @@ fn fizzbuzz(n: u32) -> () { // When a function returns `()`, the return type can be omitted from the // signature fn fizzbuzz_to(n: u32) { - for n in range(1, n + 1) { + for n in 1..(n + 1) { fizzbuzz(n); } } From 8bc426138ef37a32dbd7a13b2929323c61735f11 Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Fri, 30 Jan 2015 17:14:33 -0800 Subject: [PATCH 0095/1122] More miscellaneous grammatical fixes --- examples/attribute/crate/input.md | 2 +- examples/borrow/input.md | 2 +- examples/box/input.md | 2 +- examples/generics/impl/input.md | 4 ++-- examples/generics/input.md | 2 +- examples/generics/phantom/input.md | 2 +- examples/methods/input.md | 2 +- examples/ops/input.md | 2 +- examples/option/input.md | 2 +- examples/raii/input.md | 6 +++--- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/attribute/crate/input.md b/examples/attribute/crate/input.md index 0464f24e54..78fd3720f7 100644 --- a/examples/attribute/crate/input.md +++ b/examples/attribute/crate/input.md @@ -1,5 +1,5 @@ The `crate_type` attribute can be used to tell the compiler whether a crate is -a binary or a library (and even which type of library). And the `crate_name` +a binary or a library (and even which type of library), and the `crate_name` attribute can be used to set the name of the crate. {lib.rs} diff --git a/examples/borrow/input.md b/examples/borrow/input.md index 622d478ce0..c256dead12 100644 --- a/examples/borrow/input.md +++ b/examples/borrow/input.md @@ -1,4 +1,4 @@ -Most of the time we'll like to access some data, without taking ownership over +Most of the time, we'd like to access some data without taking ownership over it. To accomplish this, Rust provides a *borrowing* mechanism. Instead of passing objects by-value (`T`), objects can be passed by reference (`&T`). diff --git a/examples/box/input.md b/examples/box/input.md index ae4cb9bbb5..5d6cafd3e0 100644 --- a/examples/box/input.md +++ b/examples/box/input.md @@ -4,7 +4,7 @@ All values in Rust are stack allocated by default. Values can be *boxed* goes out of scope, its destructor is called, the inner object is destroyed, and the memory in the heap is freed. -Boxed values can be dereferenced using the `*` operator, this removes one layer +Boxed values can be dereferenced using the `*` operator; this removes one layer of indirection. Alternatively, the `let box x = y` pattern can be used to "unbox" `y` into `x`. diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 4606297574..a0af35e9ed 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -1,5 +1,5 @@ -Implementations can also be made generic. Generally `impl` is followed by -the type `` although it is not a strict requirement. +Implementations can also be made generic. Generally, `impl` is followed by +the type ``, although it is not a strict requirement. ```rust struct S; // A null struct diff --git a/examples/generics/input.md b/examples/generics/input.md index 6d713d6f1a..57f3c9b95e 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -1,7 +1,7 @@ Generic structs can be declared to hold generic types, and generic functions can be declared to take generic types as arguments. -Generics must be specialized when used; but, because of type inference, +Generics must be specialized when used, but, because of type inference, annotation is usually not required. When that's not the case, structs can be specialized via type annotation, and functions can be specialized passing the generic arguments using this syntax `::`. diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index e9057cdb91..62af7fa4dc 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -1,4 +1,4 @@ -A Phantom type is a data type which contains extra hidden +A phantom type is a data type which contains extra hidden generic parameters. These extra parameters hold no storage values. They are checked statically at compile time and only at compile time; they have no run-time behavior. diff --git a/examples/methods/input.md b/examples/methods/input.md index c2bde12242..6e725cfa37 100644 --- a/examples/methods/input.md +++ b/examples/methods/input.md @@ -1,4 +1,4 @@ -Methods are functions attached to objects, these methods have access to the +Methods are functions attached to objects. These methods have access to the data of the object and its other methods via the `self` keyword. Methods are defined under a `impl` block. diff --git a/examples/ops/input.md b/examples/ops/input.md index e6098704a1..fb2c783673 100644 --- a/examples/ops/input.md +++ b/examples/ops/input.md @@ -1,6 +1,6 @@ In Rust, many of the operators can be overloaded via traits. This is possible because operators are just sugar for method calls. For example, `a + b` -desugars to `a.add(b)`. This `add` method is part of the `Add` trait, hence +desugars to `a.add(b)`. This `add` method is part of the `Add` trait; hence, any implementor of the `Add` trait will be able to use the `+` operator. {operator.play} diff --git a/examples/option/input.md b/examples/option/input.md index 25548903ed..94365e77a0 100644 --- a/examples/option/input.md +++ b/examples/option/input.md @@ -1,5 +1,5 @@ Sometimes it's desirable to catch the failure of some parts of a program -instead of calling `panic!`, this can be accomplished using the `Option` enum. +instead of calling `panic!`; this can be accomplished using the `Option` enum. The `Option` enum has two variants: diff --git a/examples/raii/input.md b/examples/raii/input.md index 6b1e25c2a8..157ce87c0d 100644 --- a/examples/raii/input.md +++ b/examples/raii/input.md @@ -1,4 +1,4 @@ -Variables in Rust do more than just hold data in the stack, they can also *own* +Variables in Rust do more than just hold data in the stack: they can also *own* resources, e.g. `Box` owns memory in the heap. Because Rust enforces the [RAII][raii] discipline, whenever an object goes out of scope, its destructor is called @@ -7,7 +7,7 @@ and the resources *owned* by it are freed. This behavior shields against {raii.play} -Don't take my word for it, let's check using `valgrind` +Don't take my word for it, let's check using `valgrind`: ``` $ rustc raii.rs && valgrind ./raii @@ -27,6 +27,6 @@ $ rustc raii.rs && valgrind ./raii ==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) ``` -You'll never have to manually free memory again or worry about memory leaks! +You'll never have to manually free memory or worry about memory leaks again! [raii]: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization From fe280c3290aa1eeb460a06aed69a0ade668dae9e Mon Sep 17 00:00:00 2001 From: michaelmcgirr Date: Fri, 30 Jan 2015 22:36:23 -0800 Subject: [PATCH 0096/1122] Removed parentheses from the previous fix for fn.rs --- examples/fn/fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/fn.rs b/examples/fn/fn.rs index 9a5cd92af6..db70707a8c 100644 --- a/examples/fn/fn.rs +++ b/examples/fn/fn.rs @@ -31,7 +31,7 @@ fn fizzbuzz(n: u32) -> () { // When a function returns `()`, the return type can be omitted from the // signature fn fizzbuzz_to(n: u32) { - for n in 1..(n + 1) { + for n in 1..n + 1 { fizzbuzz(n); } } From 67102885ffa84df1ef0cf6cb105cf094e3386b87 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sat, 31 Jan 2015 22:03:59 +0000 Subject: [PATCH 0097/1122] type/inference: fix typo. --- examples/type/inference/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/type/inference/input.md b/examples/type/inference/input.md index 93670a7a94..cf592cddad 100644 --- a/examples/type/inference/input.md +++ b/examples/type/inference/input.md @@ -1,8 +1,8 @@ The type inference engine is pretty smart. It does more than looking at the type of the [r-value][rvalue] -during an initialization. It also looks how the variable is used afterwards to -infer its type. Here's an advanced example of type inference: +during an initialization. It also looks at how the variable is used afterwards +to infer its type. Here's an advanced example of type inference: {inference.play} From d35fd52bd592a85a8780b6c3649912127d8f1663 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 1 Feb 2015 11:47:24 +0000 Subject: [PATCH 0098/1122] for: fix typo. --- examples/for/input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/for/input.md b/examples/for/input.md index 99db3aa52a..de6f516723 100644 --- a/examples/for/input.md +++ b/examples/for/input.md @@ -1,7 +1,7 @@ The `for in` construct can be used to iterate an `Iterator`, a lazy value -generator (more details later). One of the easiest way to create an iterator -is to use the range notation. `a..b` will yield values from `a` (inclusive) to `b` -(exclusive) in steps of one. +generator (more details later). One of the easiest ways to create an iterator +is to use the range notation. `a..b` will yield values from `a` (inclusive) to +`b` (exclusive) in steps of one. Let's write FizzBuzz using `for` instead of `while`. From 1fc8feece228df07ad4fcb341a049972547a4ea5 Mon Sep 17 00:00:00 2001 From: Daan Rijks Date: Wed, 4 Feb 2015 18:11:02 +0100 Subject: [PATCH 0099/1122] lifetime/borrow: fix word order --- examples/lifetime/borrow/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lifetime/borrow/input.md b/examples/lifetime/borrow/input.md index a5c196801e..2014b1dd5d 100644 --- a/examples/lifetime/borrow/input.md +++ b/examples/lifetime/borrow/input.md @@ -39,8 +39,8 @@ enough". Let's analyze why this happens: The borrow checker will do this job for the programmer behind his/her back, to prevent him/her from (unintentionally) creating dangling pointers. Although, -the programmer can be saved by the borrow checker without knowing what is a -lifetime. +the programmer can be saved by the borrow checker without knowing what a +lifetime is. The programmer doesn't need to explicitly annotate lifetimes (nor understand what are lifetimes), for the borrow checker to do its job in most cases. These From 919ade5ed2f94d479fb651a599a53c6798fe03bd Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 6 Feb 2015 00:40:47 -0500 Subject: [PATCH 0100/1122] Update rust --- Cargo.lock | 8 ++++---- src/file.rs | 4 ++-- src/main.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6850b54eb..ba351fc790 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/file.rs b/src/file.rs index ae97e84c42..3f31ab16f2 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,8 +1,8 @@ +use std::env; use std::old_io::USER_RWX; use std::old_io::fs; use std::old_io::process::{Command,ProcessOutput}; use std::old_io::{File,Truncate,Write}; -use std::os; pub fn mkdir(path: &Path) { match fs::mkdir_recursive(path, USER_RWX) { @@ -22,7 +22,7 @@ pub fn read(path: &Path) -> Result { } pub fn run(prefix: &str, id: &str, src: &str) -> Result { - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); // Assume that the current working directory actually exists let out_dir = cwd.join(format!("bin/{}/{}", prefix, id)); diff --git a/src/main.rs b/src/main.rs index 096a6be44e..64e508a64c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![feature(os)] +#![feature(env)] #![feature(io)] #![feature(std_misc)] #![feature(path)] From 652002851889b5efb5991909eb5706a9d7e1b537 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 6 Feb 2015 00:41:18 -0500 Subject: [PATCH 0101/1122] Remove rand --- examples/staging/rand/derive.rs | 21 -------------- examples/staging/rand/distributions.rs | 18 ------------ examples/staging/rand/gen.rs | 40 -------------------------- examples/staging/rand/input.md | 22 -------------- examples/structure.json | 1 - 5 files changed, 102 deletions(-) delete mode 100644 examples/staging/rand/derive.rs delete mode 100644 examples/staging/rand/distributions.rs delete mode 100644 examples/staging/rand/gen.rs delete mode 100644 examples/staging/rand/input.md diff --git a/examples/staging/rand/derive.rs b/examples/staging/rand/derive.rs deleted file mode 100644 index ab73f6e2c5..0000000000 --- a/examples/staging/rand/derive.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::rand; -use std::rand::Rng; - -#[derive(Rand,Show)] -struct Point { - x: f64, - y: f64, -} - -#[derive(Rand,Show)] -struct Rectangle { - p1: Point, - p2: Point, -} - -fn main() { - let mut rng = rand::thread_rng(); - - println!("random point\n{:?}", rng.gen::()); - println!("random rectangle\n{:?}", rng.gen::()); -} diff --git a/examples/staging/rand/distributions.rs b/examples/staging/rand/distributions.rs deleted file mode 100644 index 819c139926..0000000000 --- a/examples/staging/rand/distributions.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::rand::distributions::{IndependentSample,Normal,StudentT}; -use std::rand; - -fn main() { - let mut rng = rand::thread_rng(); - - let normal = Normal::new(0.0, 1.0); - println!("10 samples from a normal distribution with mean 0.0 and SD 1.0"); - for _ in range(0u32, 10) { - println!("{}", normal.ind_sample(&mut rng)); - } - - let student = StudentT::new(5.0); - println!("10 samples from a T distribution with 5 degrees of freedom"); - for _ in range(0u32, 10) { - println!("{}", student.ind_sample(&mut rng)); - } -} diff --git a/examples/staging/rand/gen.rs b/examples/staging/rand/gen.rs deleted file mode 100644 index 175860f96d..0000000000 --- a/examples/staging/rand/gen.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::rand::Rng; -use std::rand; - -fn main() { - // create a task-local Random Number Generator - let mut rng = rand::thread_rng(); - - // the `gen` methods generates values in the full range of each type using - // a uniform distribution - println!("randomly generate some values for different primitive types"); - println!("u8: {}", rng.gen::()); - println!("i8: {}", rng.gen::()); - println!("u16: {}", rng.gen::()); - println!("i16: {}", rng.gen::()); - // except for floats which get generated in the range [0, 1> - println!("f32: {}", rng.gen::()); - println!("f64: {}", rng.gen::()); - - // `gen_iter` returns an iterator that yields a infinite number of randomly - // generated numbers - let mut v: Vec = rng.gen_iter::().take(10).collect(); - - println!("10 randomly generated u8 values"); - println!("{:?}", v.as_slice()); - - // `shuffle` shuffles a mutable slice in place - rng.shuffle(v.as_mut_slice()); - println!("shuffle previous slice"); - println!("{:?}", v.as_slice()); - - // `choose` will sample an slice *with* replacement - // i.e. the same element can be chosen more than one time - println!("sample previous slice *with* replacement 10 times"); - for _ in range(0u32, 10) { - match rng.choose(v.as_slice()) { - None => panic!("slice was empty"), - Some(x) => println!("{:?}", x), - } - } -} diff --git a/examples/staging/rand/input.md b/examples/staging/rand/input.md deleted file mode 100644 index d6316905e3..0000000000 --- a/examples/staging/rand/input.md +++ /dev/null @@ -1,22 +0,0 @@ -The `std::rand` module provides access to the Random Number Generators (RNG) -provided by the OS, which can then be used to generate random values of any -type that implements the `Rand` trait (which includes all the primitive types). - -{gen.rs} - -{gen.out} - -Several structs are available under the `std::rand::distributions` module, that -can be used to generate values using different probability distributions like: -normal, uniform, Student's T, Chi squared, Gamma, etc. - -{distributions.rs} - -{distributions.out} - -The `derive` attribute can be used to implement the `Rand` trait for custom -types, this allows generation of random values of custom types. - -{derive.rs} - -{derive.out} diff --git a/examples/structure.json b/examples/structure.json index 62eb88ab12..79d821f274 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -122,7 +122,6 @@ { "id": "matching", "title": "Argument parsing", "children": null }, { "id": "getopts", "title": "`getopts`", "children": null } ] }, - { "id": "rand", "title": "Random", "children": null }, { "id": "simd", "title": "SIMD", "children": null }, { "id": "test", "title": "Testing", "children": null }, { "id": "unsafe", "title": "Unsafe operations", "children": null }, From 953e48ec5c2632c0ab4ed29c781c586cd4f802ef Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 6 Feb 2015 00:42:25 -0500 Subject: [PATCH 0102/1122] Fix testsuite --- examples/sockets/client.rs | 5 +++-- examples/staging/arg/args.rs | 5 +++-- examples/staging/arg/getopts/echo.rs | 7 ++++--- examples/staging/arg/getopts/testopt.rs | 8 +++++--- examples/staging/arg/matching/match_args.rs | 9 +++++---- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index a5c6ae4baa..3a2f46a323 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -1,12 +1,13 @@ +use std::env; use common::SOCKET_PATH; use std::old_io::net::pipe::UnixStream; -use std::os; mod common; fn main() { // `args` returns the arguments passed to the program - let args = os::args(); + let args: Vec = env::args().map(|x| x.into_string().unwrap()) + .collect(); let socket = Path::new(SOCKET_PATH); // First argument is the message to be sent diff --git a/examples/staging/arg/args.rs b/examples/staging/arg/args.rs index 2c0ef153de..c865204830 100644 --- a/examples/staging/arg/args.rs +++ b/examples/staging/arg/args.rs @@ -1,7 +1,8 @@ -use std::os; +use std::env; fn main() { - let args = os::args(); + let args: Vec = env::args().map(|x| x.into_string().unwrap()) + .collect(); // The first argument is the path that was used to call the program. println!("My path is {}.", args[0]); // The rest of the arguments are the passed command line parameters. diff --git a/examples/staging/arg/getopts/echo.rs b/examples/staging/arg/getopts/echo.rs index d8f44ad586..f44ef3fee6 100644 --- a/examples/staging/arg/getopts/echo.rs +++ b/examples/staging/arg/getopts/echo.rs @@ -1,13 +1,14 @@ extern crate getopts; -use std::os; +use std::env; use std::old_io::{print, println}; use std::old_io::stdio; static VERSION: &'static str = "1.0.0"; fn main() { - let args = os::args(); + let args: Vec = env::args().map(|x| x.into_string().unwrap()) + .collect(); let ref program = args[0]; // Set possible flags. @@ -25,7 +26,7 @@ fn main() { Ok(m) => m, Err(f) => { println!("{}", f); - os::set_exit_status(1); + env::set_exit_status(1); return; // The exit code is 0 (success) by default. // Any exit code other than 0 indicates failure. diff --git a/examples/staging/arg/getopts/testopt.rs b/examples/staging/arg/getopts/testopt.rs index 6f10a5d8e8..be818d6794 100644 --- a/examples/staging/arg/getopts/testopt.rs +++ b/examples/staging/arg/getopts/testopt.rs @@ -1,9 +1,11 @@ extern crate getopts; -use std::os; +use std::env; fn main() { - let args = os::args(); + let args: Vec = env::args().map(|x| x.into_string().unwrap()) + .collect(); + let opts = [ getopts::optflag("a", "long_a", ""), getopts::optflag("b", "long_b", ""), @@ -17,7 +19,7 @@ fn main() { Ok(m) => m, Err(f) => { println!("{}", f); - os::set_exit_status(1); + env::set_exit_status(1); return; } }; diff --git a/examples/staging/arg/matching/match_args.rs b/examples/staging/arg/matching/match_args.rs index ec31bda6b1..069381daa2 100644 --- a/examples/staging/arg/matching/match_args.rs +++ b/examples/staging/arg/matching/match_args.rs @@ -1,4 +1,4 @@ -use std::os; +use std::env; fn increase(number: i32) { println!("{}", number + 1); @@ -17,7 +17,8 @@ match_args {{increase|decrease}} } fn main() { - let args = os::args(); + let args: Vec = env::args().map(|x| x.into_string().unwrap()) + .collect(); match args.as_slice() { // no arguments passed @@ -36,10 +37,10 @@ fn main() { [_, ref cmd, ref num] => { // parse the number let number: i32 = match num.parse() { - Some(n) => { + Ok(n) => { n }, - None => { + Err(_) => { println!("error: second argument not an integer"); help(); return; From b5eb16fcbab098fd2941104f35a78aef62ee38f7 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 6 Feb 2015 00:42:48 -0500 Subject: [PATCH 0103/1122] derive: Show -> Debug --- examples/bounds/bounds.rs | 2 +- examples/clone/clone.rs | 4 ++-- examples/generics/phantom/units/units.rs | 6 +++--- examples/lifetime/fn/fn.rs | 2 +- examples/ops/operator.rs | 4 ++-- examples/result/result.rs | 2 +- examples/result/try/try.rs | 2 +- examples/staging/fmt/input.md | 4 ++-- examples/staging/hash/hashset/hashset.rs | 4 ++-- examples/trait/derive/derive.rs | 4 ++-- examples/trait/derive/input.md | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index d71d6e051f..81c95920c7 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -1,6 +1,6 @@ use std::ops::{Add, Sub, Mul}; -#[derive(Show, Copy)] +#[derive(Debug, Copy)] struct Vec2 { x: T, y: T, diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index 19997be5a4..a6b99d19fa 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -1,11 +1,11 @@ #![feature(box_syntax)] // A unit struct without resources -#[derive(Show, Copy)] +#[derive(Debug, Copy)] struct Nil; // A tuple struct with resources that implements the `Clone` trait -#[derive(Clone,Show)] +#[derive(Clone,Debug)] struct Pair(Box, Box); fn main() { diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index e8d35597f9..2406c44b2f 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -1,13 +1,13 @@ use std::ops::Add; /// Null enumerations to define unit types -#[derive(Show, Copy)] +#[derive(Debug, Copy)] struct Inch; -#[derive(Show, Copy)] +#[derive(Debug, Copy)] struct Mm; /// Length is phantom type with hidden parameter `Unit` -#[derive(Show, Copy)] +#[derive(Debug, Copy)] struct Length(T,); /// impl X for Y {} means "implement the trait `X` for the Type `Y`" diff --git a/examples/lifetime/fn/fn.rs b/examples/lifetime/fn/fn.rs index d4b1e86a15..130d6f7a5a 100644 --- a/examples/lifetime/fn/fn.rs +++ b/examples/lifetime/fn/fn.rs @@ -1,4 +1,4 @@ -#[derive(Show)] +#[derive(Debug)] struct Triplet { one: i32, two: i32, diff --git a/examples/ops/operator.rs b/examples/ops/operator.rs index c50fcb0be1..16036c1758 100644 --- a/examples/ops/operator.rs +++ b/examples/ops/operator.rs @@ -3,10 +3,10 @@ use std::ops::Add; struct Foo; struct Bar; -#[derive(Show)] +#[derive(Debug)] struct FooBar; -#[derive(Show)] +#[derive(Debug)] struct BarFoo; // The `Add` trait needs two generic parameters: diff --git a/examples/result/result.rs b/examples/result/result.rs index 1334ae3ab0..8f8821cf94 100644 --- a/examples/result/result.rs +++ b/examples/result/result.rs @@ -2,7 +2,7 @@ mod checked { // For .ln() and .sqrt() use std::num::Float; // Mathematical "errors" we want to catch - #[derive(Show)] + #[derive(Debug)] pub enum MathError { DivisionByZero, NegativeLogarithm, diff --git a/examples/result/try/try.rs b/examples/result/try/try.rs index dee7d14028..132cbeb100 100644 --- a/examples/result/try/try.rs +++ b/examples/result/try/try.rs @@ -2,7 +2,7 @@ mod checked { // For .sqrt() and .ln() use std::num::Float; - #[derive(Show)] + #[derive(Debug)] enum MathError { DivisionByZero, NegativeLogarithm, diff --git a/examples/staging/fmt/input.md b/examples/staging/fmt/input.md index 4929ac063f..44d7ced399 100644 --- a/examples/staging/fmt/input.md +++ b/examples/staging/fmt/input.md @@ -9,14 +9,14 @@ The same variable (`foo`) can be formatted differently depending on which *argument type* is used: `X` vs `o` vs *unspecified*. This formatting functionality is implemented via traits, and there is one trait -for each argument type. The most common formatting trait is `Show`, which +for each argument type. The most common formatting trait is `Debug`, which handles cases where the argument type is left unspecified: `{}` for instance. {show.play} Here's the full list of formatting traits and their respective argument types: -* *unspecified* -> `Show` +* *unspecified* -> `Debug` * `d` and `i` -> `Signed` * `u` -> `Unsigned` * `b` -> `Bool` diff --git a/examples/staging/hash/hashset/hashset.rs b/examples/staging/hash/hashset/hashset.rs index f3ac50aa6c..a5f9b02821 100644 --- a/examples/staging/hash/hashset/hashset.rs +++ b/examples/staging/hash/hashset/hashset.rs @@ -14,8 +14,8 @@ fn main() { b.insert(5); - // If a collection's element type implements `Show`, - // then the collection implements `Show`. + // If a collection's element type implements `Debug`, + // then the collection implements `Debug`. // It usually prints its elements in the format `[elem1, elem2, ...]` println!("A: {:?}", a); println!("B: {:?}", b); diff --git a/examples/trait/derive/derive.rs b/examples/trait/derive/derive.rs index a193378eb8..3c067389eb 100644 --- a/examples/trait/derive/derive.rs +++ b/examples/trait/derive/derive.rs @@ -3,7 +3,7 @@ struct Centimeters(f64); // A tuple struct that can be printed -#[derive(Show)] +#[derive(Debug)] struct Inches(i32); impl Inches { @@ -21,7 +21,7 @@ fn main() { let _one_second = Seconds(1); // Error! `Seconds` can't be printed, because it doesn't implement the - // `Show` trait + // `Debug` trait //println!("One second looks like: {}", _one_second); // TODO ^ Try uncommenting this line diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index a600ba0f4b..6e3d45a9c8 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -25,7 +25,7 @@ This is a list of the "derivable" traits: create a zero instance of a numeric data type. * [`FromPrimitive`][from-primitive], to create an instance from a numeric primitive. -* [`Show`][show], to +* [`Debug`][debug], to format a value using the `{:?}` formatter. [attribute]: /attribute.html @@ -41,4 +41,4 @@ This is a list of the "derivable" traits: [default]: http://doc.rust-lang.org/std/default/trait.Default.html [zero]: http://doc.rust-lang.org/std/num/trait.Zero.html [from-primitive]: http://doc.rust-lang.org/std/num/trait.FromPrimitive.html -[show]: http://doc.rust-lang.org/std/fmt/trait.Show.html +[debug]: http://doc.rust-lang.org/std/fmt/trait.Debug.html From 94243331b757888989cf80379351e7b8792b380d Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Mon, 9 Feb 2015 23:16:22 -0800 Subject: [PATCH 0104/1122] Fix #447 --- examples/literals/input.md | 4 ++-- examples/print/print.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/literals/input.md b/examples/literals/input.md index aadc860767..1278564aca 100644 --- a/examples/literals/input.md +++ b/examples/literals/input.md @@ -8,8 +8,8 @@ Underscores can be inserted in numeric literals to improve readability, e.g. `1_000` is the same as `1000`, and `0.000_001` is the same as `0.000001`. We need to tell the compiler the type of the literals we use. For now, -we'll use the `u` suffix to indicate that the literal is an unsigned integer, -and the `i` suffix to indicate that it's a signed integer. We'll cover the type +we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, +and the `i32` suffix to indicate that it's a signed 32-bit integer. We'll cover the type system in [another chapter][type], and give more details about type annotating literals in [their own section][type-literal]. diff --git a/examples/print/print.rs b/examples/print/print.rs index acfc69d3bb..cd8e88c9d2 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -4,8 +4,8 @@ fn main() { // `{}` are placeholders for arguments that will be stringified println!("{} days", 31); - // The `i` suffix indicates the compiler that this literal has type: signed - // pointer size integer, see next chapter for more details + // Without a suffix, 31 becomes an i32. You can change what type 31 is, + // with a suffix, and that is covered in the next chapter. // The positional arguments can be reused along the template println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); From 61ee202230b1eb1c2f036a0d0399d4d2c559a0bf Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 11 Feb 2015 18:57:51 -0500 Subject: [PATCH 0105/1122] Make buildable --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba351fc790..bc095b4b4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] From 8b6bc2024ebfece1ac7cac91d95afe831b1199cb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 09:56:43 -0500 Subject: [PATCH 0106/1122] Update to head Rust --- examples/borrow/ref/ref.rs | 1 + examples/box/box.rs | 1 + examples/sockets/client.rs | 2 +- examples/staging/arg/args.rs | 2 +- examples/staging/arg/getopts/echo.rs | 2 +- examples/staging/arg/getopts/testopt.rs | 4 ++-- examples/staging/arg/matching/match_args.rs | 2 +- 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index 9f84dff746..aabd33bb90 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,4 +1,5 @@ #![feature(box_syntax)] +#![feature(box_patterns)] #[derive(Copy)] struct Point { x: i32, y: i32 } diff --git a/examples/box/box.rs b/examples/box/box.rs index 12b4b1293f..0e0746c3a5 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,4 +1,5 @@ #![feature(box_syntax)] +#![feature(box_patterns)] use std::mem; diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index 3a2f46a323..3a502a862f 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -6,7 +6,7 @@ mod common; fn main() { // `args` returns the arguments passed to the program - let args: Vec = env::args().map(|x| x.into_string().unwrap()) + let args: Vec = env::args().map(|x| x.to_string()) .collect(); let socket = Path::new(SOCKET_PATH); diff --git a/examples/staging/arg/args.rs b/examples/staging/arg/args.rs index c865204830..329e450789 100644 --- a/examples/staging/arg/args.rs +++ b/examples/staging/arg/args.rs @@ -1,7 +1,7 @@ use std::env; fn main() { - let args: Vec = env::args().map(|x| x.into_string().unwrap()) + let args: Vec = env::args().map(|x| x.to_string()) .collect(); // The first argument is the path that was used to call the program. println!("My path is {}.", args[0]); diff --git a/examples/staging/arg/getopts/echo.rs b/examples/staging/arg/getopts/echo.rs index f44ef3fee6..ce428b8ac4 100644 --- a/examples/staging/arg/getopts/echo.rs +++ b/examples/staging/arg/getopts/echo.rs @@ -7,7 +7,7 @@ use std::old_io::stdio; static VERSION: &'static str = "1.0.0"; fn main() { - let args: Vec = env::args().map(|x| x.into_string().unwrap()) + let args: Vec = env::args().map(|x| x.to_string()) .collect(); let ref program = args[0]; diff --git a/examples/staging/arg/getopts/testopt.rs b/examples/staging/arg/getopts/testopt.rs index be818d6794..98c853218d 100644 --- a/examples/staging/arg/getopts/testopt.rs +++ b/examples/staging/arg/getopts/testopt.rs @@ -3,9 +3,9 @@ extern crate getopts; use std::env; fn main() { - let args: Vec = env::args().map(|x| x.into_string().unwrap()) + let args: Vec = env::args().map(|x| x.to_string()) .collect(); - + let opts = [ getopts::optflag("a", "long_a", ""), getopts::optflag("b", "long_b", ""), diff --git a/examples/staging/arg/matching/match_args.rs b/examples/staging/arg/matching/match_args.rs index 069381daa2..3948943d25 100644 --- a/examples/staging/arg/matching/match_args.rs +++ b/examples/staging/arg/matching/match_args.rs @@ -17,7 +17,7 @@ match_args {{increase|decrease}} } fn main() { - let args: Vec = env::args().map(|x| x.into_string().unwrap()) + let args: Vec = env::args().map(|x| x.to_string()) .collect(); match args.as_slice() { From c6ec7fe8c6c27ef67cb8b189076654927d42570d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 10:21:11 -0500 Subject: [PATCH 0107/1122] add features where appropriate. --- examples/channels/channels.rs | 6 ++++-- examples/enum/c-like/c-like.rs | 2 ++ examples/file/create/create.rs | 3 +++ examples/file/open/open.rs | 3 +++ examples/fs/fs.rs | 5 ++++- examples/hof/hof.rs | 2 ++ examples/lifetime/explicit/explicit.rs | 3 +++ examples/literals/literals.rs | 2 ++ examples/path/path.rs | 3 +++ examples/process/pipe/pipe.rs | 2 ++ examples/process/process.rs | 6 ++++-- examples/process/wait/wait.rs | 2 ++ examples/raii/raii.rs | 1 + examples/sockets/client.rs | 5 +++++ examples/sockets/server.rs | 3 +++ examples/staging/arg/args.rs | 2 ++ examples/staging/arg/getopts/echo.rs | 6 ++++++ examples/staging/arg/getopts/testopt.rs | 4 ++++ examples/staging/arg/matching/match_args.rs | 3 +++ examples/staging/bench/bench.rs | 3 +++ examples/staging/fmt/show.rs | 2 ++ examples/staging/hash/alt-key-types/alt-key-types.rs | 2 ++ examples/staging/macros/dry/dry.rs | 2 ++ examples/staging/simd/simd.rs | 2 ++ examples/staging/simd/simd_add.rs | 3 +++ examples/str/str.rs | 3 +++ examples/threads/threads.rs | 3 +++ examples/timers/timers.rs | 4 ++++ 28 files changed, 82 insertions(+), 5 deletions(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 4a78e2f5a7..45bd9cff1f 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -1,3 +1,5 @@ +#![feature(std_misc)] + use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; use std::thread::Thread; @@ -10,7 +12,7 @@ fn main() { // (type annotation is superfluous) let (tx, rx): (Sender, Receiver) = mpsc::channel(); - for id in range(0, NTHREADS) { + for id in 0..NTHREADS { // The sender endpoint can be copied let thread_tx = tx.clone(); @@ -28,7 +30,7 @@ fn main() { // Here, all the messages are collected let mut ids = Vec::with_capacity(NTHREADS); - for _ in range(0, NTHREADS) { + for _ in 0..NTHREADS { // The `recv` method picks a message from the channel // `recv` will block the current thread if there no messages available ids.push(rx.recv()); diff --git a/examples/enum/c-like/c-like.rs b/examples/enum/c-like/c-like.rs index ec7afa53c2..8f7dd66ac2 100644 --- a/examples/enum/c-like/c-like.rs +++ b/examples/enum/c-like/c-like.rs @@ -1,3 +1,5 @@ +#![feature(core)] + // If you'd like to refer to the days without saying // `Day::Monday`, then you use the following notation // use Day::{ diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 473551946a..b161f8f0e7 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,3 +1,6 @@ +#![feature(io)] +#![feature(path)] + use std::old_io::File; static LOREM_IPSUM: &'static str = diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index cd9dcc620e..5c03e168ae 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,3 +1,6 @@ +#![feature(io)] +#![feature(path)] + use std::old_io::File; fn main() { diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 92468f14b7..8a1bccdbf1 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -1,3 +1,6 @@ +#![feature(io)] +#![feature(path)] + use std::old_io::fs; use std::old_io::fs::PathExtensions; use std::old_io::{File, IoResult, USER_RWX}; @@ -73,7 +76,7 @@ fn main() { // `Directories`, which implements the `Iterator trait match fs::walk_dir(&Path::new("a")) { Err(why) => println!("! {:?}", why.kind), - Ok(mut paths) => for path in paths { + Ok(paths) => for path in paths { println!("> {}", path.display()); }, } diff --git a/examples/hof/hof.rs b/examples/hof/hof.rs index 8daf6014d7..7b40a406e1 100644 --- a/examples/hof/hof.rs +++ b/examples/hof/hof.rs @@ -1,3 +1,5 @@ +#![feature(core)] + // The `AdditiveIterator` trait adds the `sum` method to iterators use std::iter::AdditiveIterator; use std::iter; diff --git a/examples/lifetime/explicit/explicit.rs b/examples/lifetime/explicit/explicit.rs index 05605aebc5..2523d257c0 100644 --- a/examples/lifetime/explicit/explicit.rs +++ b/examples/lifetime/explicit/explicit.rs @@ -1,3 +1,6 @@ +#![feature(core)] +#![feature(collections)] + struct Book { // `String` is a heap allocated string title: String, diff --git a/examples/literals/literals.rs b/examples/literals/literals.rs index f8d70f7dc7..20a93bdbd0 100644 --- a/examples/literals/literals.rs +++ b/examples/literals/literals.rs @@ -1,3 +1,5 @@ +#![feature(core)] + fn main() { // Integer addition println!("1 + 2 = {}", 1u32 + 2); diff --git a/examples/path/path.rs b/examples/path/path.rs index eac18da8e0..8d88b64877 100644 --- a/examples/path/path.rs +++ b/examples/path/path.rs @@ -1,3 +1,6 @@ +#![feature(path)] +#![feature(io)] + use std::old_io::fs::PathExtensions; fn main() { diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index 565d292acc..eb1ed81b12 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,3 +1,5 @@ +#![feature(io)] + use std::old_io::process::Command; static PANGRAM: &'static str = diff --git a/examples/process/process.rs b/examples/process/process.rs index 7d80c2a7fe..231163afba 100644 --- a/examples/process/process.rs +++ b/examples/process/process.rs @@ -1,3 +1,5 @@ +#![feature(io)] + use std::old_io::process::{Command,ProcessOutput}; fn main() { @@ -15,12 +17,12 @@ fn main() { // Check if the process succeeded, i.e. the exit code was 0 if exit.success() { // `out` has type `Vec`, convert it to a UTF-8 `$str` - let s = String::from_utf8_lossy(out.as_slice()); + let s = String::from_utf8_lossy(&out); print!("rustc succeeded and stdout was:\n{}", s); } else { // `err` also has type `Vec` - let s = String::from_utf8_lossy(err.as_slice()); + let s = String::from_utf8_lossy(&err); print!("rustc failed and stderr was:\n{}", s); } diff --git a/examples/process/wait/wait.rs b/examples/process/wait/wait.rs index 296953e3ff..ca3769b843 100644 --- a/examples/process/wait/wait.rs +++ b/examples/process/wait/wait.rs @@ -1,3 +1,5 @@ +#![feature(io)] + use std::old_io::process::Command; fn main() { diff --git a/examples/raii/raii.rs b/examples/raii/raii.rs index d480da1c6c..d6032a0e4d 100644 --- a/examples/raii/raii.rs +++ b/examples/raii/raii.rs @@ -1,4 +1,5 @@ #![feature(box_syntax)] +#![feature(core)] fn create_box() { // Allocate an integer in the heap diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index 3a502a862f..f4ccb09504 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -1,3 +1,8 @@ +#![feature(io)] +#![feature(core)] +#![feature(path)] +#![feature(env)] + use std::env; use common::SOCKET_PATH; use std::old_io::net::pipe::UnixStream; diff --git a/examples/sockets/server.rs b/examples/sockets/server.rs index 0dcc1b3f77..3249fbf21e 100644 --- a/examples/sockets/server.rs +++ b/examples/sockets/server.rs @@ -1,3 +1,6 @@ +#![feature(io)] +#![feature(path)] + use common::SOCKET_PATH; use std::old_io::fs; use std::old_io::fs::PathExtensions; diff --git a/examples/staging/arg/args.rs b/examples/staging/arg/args.rs index 329e450789..6596648926 100644 --- a/examples/staging/arg/args.rs +++ b/examples/staging/arg/args.rs @@ -1,3 +1,5 @@ +#![feature(env)] + use std::env; fn main() { diff --git a/examples/staging/arg/getopts/echo.rs b/examples/staging/arg/getopts/echo.rs index ce428b8ac4..fcdef6f78d 100644 --- a/examples/staging/arg/getopts/echo.rs +++ b/examples/staging/arg/getopts/echo.rs @@ -1,3 +1,9 @@ +#![feature(io)] +#![feature(rustc_private)] +#![feature(core)] +#![feature(env)] +#![feature(collections)] + extern crate getopts; use std::env; diff --git a/examples/staging/arg/getopts/testopt.rs b/examples/staging/arg/getopts/testopt.rs index 98c853218d..ab457e8107 100644 --- a/examples/staging/arg/getopts/testopt.rs +++ b/examples/staging/arg/getopts/testopt.rs @@ -1,3 +1,7 @@ +#![feature(rustc_private)] +#![feature(collections)] +#![feature(env)] + extern crate getopts; use std::env; diff --git a/examples/staging/arg/matching/match_args.rs b/examples/staging/arg/matching/match_args.rs index 3948943d25..bdb9acf1c0 100644 --- a/examples/staging/arg/matching/match_args.rs +++ b/examples/staging/arg/matching/match_args.rs @@ -1,3 +1,6 @@ +#![feature(core)] +#![feature(env)] + use std::env; fn increase(number: i32) { diff --git a/examples/staging/bench/bench.rs b/examples/staging/bench/bench.rs index 6459ccf656..7b4ff8d51d 100644 --- a/examples/staging/bench/bench.rs +++ b/examples/staging/bench/bench.rs @@ -1,3 +1,6 @@ +#![feature(test)] +#![feature(core)] + extern crate test; use std::mem::replace; diff --git a/examples/staging/fmt/show.rs b/examples/staging/fmt/show.rs index 6b06cab457..c2f38059ed 100644 --- a/examples/staging/fmt/show.rs +++ b/examples/staging/fmt/show.rs @@ -1,3 +1,5 @@ +#![feature(core)] + use std::fmt::{self, Formatter, Display}; // For .abs() use std::num::Float; diff --git a/examples/staging/hash/alt-key-types/alt-key-types.rs b/examples/staging/hash/alt-key-types/alt-key-types.rs index 19103b4ba1..2e8a6e6e61 100644 --- a/examples/staging/hash/alt-key-types/alt-key-types.rs +++ b/examples/staging/hash/alt-key-types/alt-key-types.rs @@ -1,3 +1,5 @@ +#![feature(hash)] + use std::collections::HashMap; // Eq requires that you derive PartialEq on the type. diff --git a/examples/staging/macros/dry/dry.rs b/examples/staging/macros/dry/dry.rs index 15f0094b7c..0b005f97b0 100644 --- a/examples/staging/macros/dry/dry.rs +++ b/examples/staging/macros/dry/dry.rs @@ -1,3 +1,5 @@ +#![feature(core)] + use std::iter; use std::ops::{Add, Mul, Sub}; diff --git a/examples/staging/simd/simd.rs b/examples/staging/simd/simd.rs index 4f7055eccb..bdc8c2491c 100644 --- a/examples/staging/simd/simd.rs +++ b/examples/staging/simd/simd.rs @@ -1,3 +1,5 @@ +#![feature(core)] + use std::simd::f32x4; fn main() { diff --git a/examples/staging/simd/simd_add.rs b/examples/staging/simd/simd_add.rs index 3e5b1d874f..7aa58b778b 100644 --- a/examples/staging/simd/simd_add.rs +++ b/examples/staging/simd/simd_add.rs @@ -1,3 +1,6 @@ +#![feature(test)] +#![feature(core)] + use std::simd::f32x4; macro_rules! assert_equal_len { diff --git a/examples/str/str.rs b/examples/str/str.rs index 4566337c6b..2cfbd660d5 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -1,3 +1,6 @@ +#![feature(collections)] +#![feature(core)] + fn main() { // (all the type annotations are superfluous) // A reference to a string allocated in read only memory diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index 033b0d813e..d96809f846 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,3 +1,6 @@ +#![feature(core)] +#![feature(std_misc)] + use std::thread::Thread; static NTHREADS: i32 = 10; diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 46560cfb47..0910f684c1 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -1,3 +1,7 @@ +#![feature(core)] +#![feature(io)] +#![feature(std_misc)] + use std::old_io::Timer; use std::old_io::timer; use std::time::duration::Duration; From 95e898f714ea82dcbe7f8a52acfb6f054bcb9c8d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 11:05:24 -0500 Subject: [PATCH 0108/1122] Remove todos --- examples/structure.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/structure.json b/examples/structure.json index 79d821f274..a1ad61bcfb 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -130,15 +130,5 @@ { "id": "alt-key-types", "title": "Alternate/custom key types", "children": null}, { "id": "hashset", "title": "HashSet", "children": null } ] } - ] }, - { "id": "todo", "title": "TODO", "children": [ - { "id": "assert", "title": "assert! and debug_assert!", "children": null }, - { "id": "green", "title": "Green threads", "children": null }, - { "id": "log", "title": "Logging", "children": null }, - { "id": "rc", "title": "Reference counting", "children": null }, - { "id": "regex", "title": "Regex", "children": null }, - { "id": "rustdoc", "title": "rustdoc", "children": null }, - { "id": "select", "title": "select!", "children": null }, - { "id": "stdio", "title": "Standard I/O", "children": null } ] } ] From c203feaa414a338d286d5d1fff48236787bf6c0a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 11:16:49 -0500 Subject: [PATCH 0109/1122] Remove staging. It's all a work in progress, no need to add complexity. --- examples/{staging => }/arg/args.rs | 0 examples/{staging => }/arg/getopts/echo.rs | 0 examples/{staging => }/arg/getopts/input.md | 0 examples/{staging => }/arg/getopts/test.sh | 0 examples/{staging => }/arg/getopts/testopt.rs | 0 examples/{staging => }/arg/input.md | 0 examples/{staging => }/arg/matching/input.md | 0 .../{staging => }/arg/matching/match_args.rs | 0 examples/{staging => }/bench/bench.rs | 0 examples/{staging => }/bench/input.md | 0 examples/{staging => }/comment/comment.rs | 0 .../comment/doc-comment/doc-comment.rs | 0 .../comment/doc-comment/input.md | 0 examples/{staging => }/comment/input.md | 0 examples/{staging => }/ffi/ffi.rs | 0 examples/{staging => }/ffi/input.md | 0 examples/{staging => }/ffi/safe.rs | 0 examples/{staging => }/fmt/input.md | 0 examples/{staging => }/fmt/show.rs | 0 .../hash/alt-key-types/alt-key-types.rs | 0 .../{staging => }/hash/alt-key-types/input.md | 0 examples/{staging => }/hash/hash.rs | 0 .../{staging => }/hash/hashset/hashset.rs | 0 examples/{staging => }/hash/hashset/input.md | 0 examples/{staging => }/hash/input.md | 0 examples/{staging => }/input.md | 0 .../macros/designators/designators.rs | 0 .../{staging => }/macros/designators/input.md | 0 examples/{staging => }/macros/dry/dry.rs | 0 examples/{staging => }/macros/dry/input.md | 0 examples/{staging => }/macros/input.md | 0 .../{staging => }/macros/overload/input.md | 0 .../{staging => }/macros/overload/overload.rs | 0 examples/{staging => }/macros/repeat/input.md | 0 .../{staging => }/macros/repeat/repeat.rs | 0 examples/{staging => }/macros/simple.rs | 0 examples/{staging => }/simd/input.md | 0 examples/{staging => }/simd/simd.rs | 0 examples/{staging => }/simd/simd_add.rs | 0 examples/structure.json | 46 +++++++++---------- examples/{staging => }/test/fail.rs | 0 examples/{staging => }/test/input.md | 0 examples/{staging => }/test/unit-test.rs | 0 examples/{staging => }/unsafe/asm.rs | 0 examples/{staging => }/unsafe/input.md | 0 examples/{staging => }/unsafe/pointer.rs | 0 examples/{staging => }/unsafe/transmute.rs | 0 47 files changed, 22 insertions(+), 24 deletions(-) rename examples/{staging => }/arg/args.rs (100%) rename examples/{staging => }/arg/getopts/echo.rs (100%) rename examples/{staging => }/arg/getopts/input.md (100%) rename examples/{staging => }/arg/getopts/test.sh (100%) rename examples/{staging => }/arg/getopts/testopt.rs (100%) rename examples/{staging => }/arg/input.md (100%) rename examples/{staging => }/arg/matching/input.md (100%) rename examples/{staging => }/arg/matching/match_args.rs (100%) rename examples/{staging => }/bench/bench.rs (100%) rename examples/{staging => }/bench/input.md (100%) rename examples/{staging => }/comment/comment.rs (100%) rename examples/{staging => }/comment/doc-comment/doc-comment.rs (100%) rename examples/{staging => }/comment/doc-comment/input.md (100%) rename examples/{staging => }/comment/input.md (100%) rename examples/{staging => }/ffi/ffi.rs (100%) rename examples/{staging => }/ffi/input.md (100%) rename examples/{staging => }/ffi/safe.rs (100%) rename examples/{staging => }/fmt/input.md (100%) rename examples/{staging => }/fmt/show.rs (100%) rename examples/{staging => }/hash/alt-key-types/alt-key-types.rs (100%) rename examples/{staging => }/hash/alt-key-types/input.md (100%) rename examples/{staging => }/hash/hash.rs (100%) rename examples/{staging => }/hash/hashset/hashset.rs (100%) rename examples/{staging => }/hash/hashset/input.md (100%) rename examples/{staging => }/hash/input.md (100%) rename examples/{staging => }/input.md (100%) rename examples/{staging => }/macros/designators/designators.rs (100%) rename examples/{staging => }/macros/designators/input.md (100%) rename examples/{staging => }/macros/dry/dry.rs (100%) rename examples/{staging => }/macros/dry/input.md (100%) rename examples/{staging => }/macros/input.md (100%) rename examples/{staging => }/macros/overload/input.md (100%) rename examples/{staging => }/macros/overload/overload.rs (100%) rename examples/{staging => }/macros/repeat/input.md (100%) rename examples/{staging => }/macros/repeat/repeat.rs (100%) rename examples/{staging => }/macros/simple.rs (100%) rename examples/{staging => }/simd/input.md (100%) rename examples/{staging => }/simd/simd.rs (100%) rename examples/{staging => }/simd/simd_add.rs (100%) rename examples/{staging => }/test/fail.rs (100%) rename examples/{staging => }/test/input.md (100%) rename examples/{staging => }/test/unit-test.rs (100%) rename examples/{staging => }/unsafe/asm.rs (100%) rename examples/{staging => }/unsafe/input.md (100%) rename examples/{staging => }/unsafe/pointer.rs (100%) rename examples/{staging => }/unsafe/transmute.rs (100%) diff --git a/examples/staging/arg/args.rs b/examples/arg/args.rs similarity index 100% rename from examples/staging/arg/args.rs rename to examples/arg/args.rs diff --git a/examples/staging/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs similarity index 100% rename from examples/staging/arg/getopts/echo.rs rename to examples/arg/getopts/echo.rs diff --git a/examples/staging/arg/getopts/input.md b/examples/arg/getopts/input.md similarity index 100% rename from examples/staging/arg/getopts/input.md rename to examples/arg/getopts/input.md diff --git a/examples/staging/arg/getopts/test.sh b/examples/arg/getopts/test.sh similarity index 100% rename from examples/staging/arg/getopts/test.sh rename to examples/arg/getopts/test.sh diff --git a/examples/staging/arg/getopts/testopt.rs b/examples/arg/getopts/testopt.rs similarity index 100% rename from examples/staging/arg/getopts/testopt.rs rename to examples/arg/getopts/testopt.rs diff --git a/examples/staging/arg/input.md b/examples/arg/input.md similarity index 100% rename from examples/staging/arg/input.md rename to examples/arg/input.md diff --git a/examples/staging/arg/matching/input.md b/examples/arg/matching/input.md similarity index 100% rename from examples/staging/arg/matching/input.md rename to examples/arg/matching/input.md diff --git a/examples/staging/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs similarity index 100% rename from examples/staging/arg/matching/match_args.rs rename to examples/arg/matching/match_args.rs diff --git a/examples/staging/bench/bench.rs b/examples/bench/bench.rs similarity index 100% rename from examples/staging/bench/bench.rs rename to examples/bench/bench.rs diff --git a/examples/staging/bench/input.md b/examples/bench/input.md similarity index 100% rename from examples/staging/bench/input.md rename to examples/bench/input.md diff --git a/examples/staging/comment/comment.rs b/examples/comment/comment.rs similarity index 100% rename from examples/staging/comment/comment.rs rename to examples/comment/comment.rs diff --git a/examples/staging/comment/doc-comment/doc-comment.rs b/examples/comment/doc-comment/doc-comment.rs similarity index 100% rename from examples/staging/comment/doc-comment/doc-comment.rs rename to examples/comment/doc-comment/doc-comment.rs diff --git a/examples/staging/comment/doc-comment/input.md b/examples/comment/doc-comment/input.md similarity index 100% rename from examples/staging/comment/doc-comment/input.md rename to examples/comment/doc-comment/input.md diff --git a/examples/staging/comment/input.md b/examples/comment/input.md similarity index 100% rename from examples/staging/comment/input.md rename to examples/comment/input.md diff --git a/examples/staging/ffi/ffi.rs b/examples/ffi/ffi.rs similarity index 100% rename from examples/staging/ffi/ffi.rs rename to examples/ffi/ffi.rs diff --git a/examples/staging/ffi/input.md b/examples/ffi/input.md similarity index 100% rename from examples/staging/ffi/input.md rename to examples/ffi/input.md diff --git a/examples/staging/ffi/safe.rs b/examples/ffi/safe.rs similarity index 100% rename from examples/staging/ffi/safe.rs rename to examples/ffi/safe.rs diff --git a/examples/staging/fmt/input.md b/examples/fmt/input.md similarity index 100% rename from examples/staging/fmt/input.md rename to examples/fmt/input.md diff --git a/examples/staging/fmt/show.rs b/examples/fmt/show.rs similarity index 100% rename from examples/staging/fmt/show.rs rename to examples/fmt/show.rs diff --git a/examples/staging/hash/alt-key-types/alt-key-types.rs b/examples/hash/alt-key-types/alt-key-types.rs similarity index 100% rename from examples/staging/hash/alt-key-types/alt-key-types.rs rename to examples/hash/alt-key-types/alt-key-types.rs diff --git a/examples/staging/hash/alt-key-types/input.md b/examples/hash/alt-key-types/input.md similarity index 100% rename from examples/staging/hash/alt-key-types/input.md rename to examples/hash/alt-key-types/input.md diff --git a/examples/staging/hash/hash.rs b/examples/hash/hash.rs similarity index 100% rename from examples/staging/hash/hash.rs rename to examples/hash/hash.rs diff --git a/examples/staging/hash/hashset/hashset.rs b/examples/hash/hashset/hashset.rs similarity index 100% rename from examples/staging/hash/hashset/hashset.rs rename to examples/hash/hashset/hashset.rs diff --git a/examples/staging/hash/hashset/input.md b/examples/hash/hashset/input.md similarity index 100% rename from examples/staging/hash/hashset/input.md rename to examples/hash/hashset/input.md diff --git a/examples/staging/hash/input.md b/examples/hash/input.md similarity index 100% rename from examples/staging/hash/input.md rename to examples/hash/input.md diff --git a/examples/staging/input.md b/examples/input.md similarity index 100% rename from examples/staging/input.md rename to examples/input.md diff --git a/examples/staging/macros/designators/designators.rs b/examples/macros/designators/designators.rs similarity index 100% rename from examples/staging/macros/designators/designators.rs rename to examples/macros/designators/designators.rs diff --git a/examples/staging/macros/designators/input.md b/examples/macros/designators/input.md similarity index 100% rename from examples/staging/macros/designators/input.md rename to examples/macros/designators/input.md diff --git a/examples/staging/macros/dry/dry.rs b/examples/macros/dry/dry.rs similarity index 100% rename from examples/staging/macros/dry/dry.rs rename to examples/macros/dry/dry.rs diff --git a/examples/staging/macros/dry/input.md b/examples/macros/dry/input.md similarity index 100% rename from examples/staging/macros/dry/input.md rename to examples/macros/dry/input.md diff --git a/examples/staging/macros/input.md b/examples/macros/input.md similarity index 100% rename from examples/staging/macros/input.md rename to examples/macros/input.md diff --git a/examples/staging/macros/overload/input.md b/examples/macros/overload/input.md similarity index 100% rename from examples/staging/macros/overload/input.md rename to examples/macros/overload/input.md diff --git a/examples/staging/macros/overload/overload.rs b/examples/macros/overload/overload.rs similarity index 100% rename from examples/staging/macros/overload/overload.rs rename to examples/macros/overload/overload.rs diff --git a/examples/staging/macros/repeat/input.md b/examples/macros/repeat/input.md similarity index 100% rename from examples/staging/macros/repeat/input.md rename to examples/macros/repeat/input.md diff --git a/examples/staging/macros/repeat/repeat.rs b/examples/macros/repeat/repeat.rs similarity index 100% rename from examples/staging/macros/repeat/repeat.rs rename to examples/macros/repeat/repeat.rs diff --git a/examples/staging/macros/simple.rs b/examples/macros/simple.rs similarity index 100% rename from examples/staging/macros/simple.rs rename to examples/macros/simple.rs diff --git a/examples/staging/simd/input.md b/examples/simd/input.md similarity index 100% rename from examples/staging/simd/input.md rename to examples/simd/input.md diff --git a/examples/staging/simd/simd.rs b/examples/simd/simd.rs similarity index 100% rename from examples/staging/simd/simd.rs rename to examples/simd/simd.rs diff --git a/examples/staging/simd/simd_add.rs b/examples/simd/simd_add.rs similarity index 100% rename from examples/staging/simd/simd_add.rs rename to examples/simd/simd_add.rs diff --git a/examples/structure.json b/examples/structure.json index a1ad61bcfb..748ba808dd 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -106,29 +106,27 @@ { "id": "wait", "title": "Wait", "children": null } ] }, { "id": "fs", "title": "Filesystem Operations", "children": null }, - { "id": "staging", "title": "Staging Area", "children": [ - { "id": "bench", "title": "Benchmarking", "children": null }, - { "id": "comment", "title": "Comments", "children": [ - { "id": "doc-comment", "title": "Doc Comments", "children": null } - ] }, - { "id": "ffi", "title": "Foreign Function Interface", "children": null }, - { "id": "macros", "title": "macro_rules!", "children": [ - { "id": "designators", "title": "Designators", "children": null }, - { "id": "overload", "title": "Overload", "children": null }, - { "id": "repeat", "title": "Repeat", "children": null }, - { "id": "dry", "title": "DRY", "children": null } - ] }, - { "id": "arg", "title": "Program arguments", "children": [ - { "id": "matching", "title": "Argument parsing", "children": null }, - { "id": "getopts", "title": "`getopts`", "children": null } - ] }, - { "id": "simd", "title": "SIMD", "children": null }, - { "id": "test", "title": "Testing", "children": null }, - { "id": "unsafe", "title": "Unsafe operations", "children": null }, - { "id": "fmt", "title": "Formatting", "children": null }, - { "id": "hash", "title": "HashMap", "children": [ - { "id": "alt-key-types", "title": "Alternate/custom key types", "children": null}, - { "id": "hashset", "title": "HashSet", "children": null } - ] } + { "id": "bench", "title": "Benchmarking", "children": null }, + { "id": "comment", "title": "Comments", "children": [ + { "id": "doc-comment", "title": "Doc Comments", "children": null } + ] }, + { "id": "ffi", "title": "Foreign Function Interface", "children": null }, + { "id": "macros", "title": "macro_rules!", "children": [ + { "id": "designators", "title": "Designators", "children": null }, + { "id": "overload", "title": "Overload", "children": null }, + { "id": "repeat", "title": "Repeat", "children": null }, + { "id": "dry", "title": "DRY", "children": null } + ] }, + { "id": "arg", "title": "Program arguments", "children": [ + { "id": "matching", "title": "Argument parsing", "children": null }, + { "id": "getopts", "title": "`getopts`", "children": null } + ] }, + { "id": "simd", "title": "SIMD", "children": null }, + { "id": "test", "title": "Testing", "children": null }, + { "id": "unsafe", "title": "Unsafe operations", "children": null }, + { "id": "fmt", "title": "Formatting", "children": null }, + { "id": "hash", "title": "HashMap", "children": [ + { "id": "alt-key-types", "title": "Alternate/custom key types", "children": null}, + { "id": "hashset", "title": "HashSet", "children": null } ] } ] diff --git a/examples/staging/test/fail.rs b/examples/test/fail.rs similarity index 100% rename from examples/staging/test/fail.rs rename to examples/test/fail.rs diff --git a/examples/staging/test/input.md b/examples/test/input.md similarity index 100% rename from examples/staging/test/input.md rename to examples/test/input.md diff --git a/examples/staging/test/unit-test.rs b/examples/test/unit-test.rs similarity index 100% rename from examples/staging/test/unit-test.rs rename to examples/test/unit-test.rs diff --git a/examples/staging/unsafe/asm.rs b/examples/unsafe/asm.rs similarity index 100% rename from examples/staging/unsafe/asm.rs rename to examples/unsafe/asm.rs diff --git a/examples/staging/unsafe/input.md b/examples/unsafe/input.md similarity index 100% rename from examples/staging/unsafe/input.md rename to examples/unsafe/input.md diff --git a/examples/staging/unsafe/pointer.rs b/examples/unsafe/pointer.rs similarity index 100% rename from examples/staging/unsafe/pointer.rs rename to examples/unsafe/pointer.rs diff --git a/examples/staging/unsafe/transmute.rs b/examples/unsafe/transmute.rs similarity index 100% rename from examples/staging/unsafe/transmute.rs rename to examples/unsafe/transmute.rs From 1bf1142f093e00e26786ab920a8da22013fa6451 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 12:36:06 -0500 Subject: [PATCH 0110/1122] Refer to scoped instead of spawn. Fixes #442. --- examples/threads/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/threads/input.md b/examples/threads/input.md index be072180b7..6c8e1d05f2 100644 --- a/examples/threads/input.md +++ b/examples/threads/input.md @@ -1,4 +1,4 @@ -Rust provides a mechanism for spawning native OS threads via the `spawn` +Rust provides a mechanism for spawning native OS threads via the `scoped` function, the argument of this function is a moving closure. {threads.play} From f3f947cc0a25c352e21066f2d03664de882fb002 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 12:37:54 -0500 Subject: [PATCH 0111/1122] Link to the reference for cfg values Fixes #446 --- examples/attribute/cfg/input.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md index 1d473f39f4..2a255e65fd 100644 --- a/examples/attribute/cfg/input.md +++ b/examples/attribute/cfg/input.md @@ -1,3 +1,7 @@ The `cfg` attribute can be use to achieve conditional compilation. {cfg.play} + +See [the +Reference](http://doc.rust-lang.org/reference.html#conditional-compilation) for +more details. From e5b5758433c403a559b5dbe95007a99ea11a5719 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 12:46:03 -0500 Subject: [PATCH 0112/1122] range -> .. Fixes #389 --- examples/bench/bench.rs | 3 +-- examples/iter/iter.rs | 4 ++-- examples/macros/dry/dry.rs | 4 +--- examples/raii/raii.rs | 3 +-- examples/simd/simd_add.rs | 4 ++-- examples/threads/threads.rs | 3 +-- examples/vec/vec.rs | 4 ++-- src/main.rs | 2 +- 8 files changed, 11 insertions(+), 16 deletions(-) diff --git a/examples/bench/bench.rs b/examples/bench/bench.rs index 7b4ff8d51d..f549587fbf 100644 --- a/examples/bench/bench.rs +++ b/examples/bench/bench.rs @@ -1,5 +1,4 @@ #![feature(test)] -#![feature(core)] extern crate test; @@ -44,7 +43,7 @@ fn recursive_fibonacci(b: &mut Bencher) { // exact code to benchmark must be passed as a closure to the iter // method of Bencher b.iter(|| { - range(0, BENCH_SIZE).map(fibonacci).collect::>() + (0..BENCH_SIZE).map(fibonacci).collect::>() }) } diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index f9ad67812c..fe8d47a165 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -29,7 +29,7 @@ fn main() { // Iterator that generates: 0, 1 and 2 let mut sequence = 0..3; - println!("Four consecutive `next` calls on range(0, 3)"); + println!("Four consecutive `next` calls on 0..3"); println!("> {:?}", sequence.next()); println!("> {:?}", sequence.next()); println!("> {:?}", sequence.next()); @@ -37,7 +37,7 @@ fn main() { // The for construct will iterate an 'Iterator' until it returns 'None'. // Every 'Some' value is unwrapped and bound to a variable. - println!("Iterate over range(0, 3) using for"); + println!("Iterate over 0..3 using for"); for i in 0..3 { println!("> {}", i); } diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index 0b005f97b0..59ec3f2a37 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -1,5 +1,3 @@ -#![feature(core)] - use std::iter; use std::ops::{Add, Mul, Sub}; @@ -48,7 +46,7 @@ mod test { ($func: ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { - for size in range(0u32, 10) { + for size in 0u32..10 { let mut x: Vec<_> = iter::repeat(size).take($x).collect(); let y: Vec<_> = iter::repeat(size).take($y).collect(); let z: Vec<_> = iter::repeat(size).take($z).collect(); diff --git a/examples/raii/raii.rs b/examples/raii/raii.rs index d6032a0e4d..18a9ed32a5 100644 --- a/examples/raii/raii.rs +++ b/examples/raii/raii.rs @@ -1,5 +1,4 @@ #![feature(box_syntax)] -#![feature(core)] fn create_box() { // Allocate an integer in the heap @@ -21,7 +20,7 @@ fn main() { } // Create lots of boxes - for _ in range(0u32, 1_000) { + for _ in 0u32..1_000 { create_box(); } diff --git a/examples/simd/simd_add.rs b/examples/simd/simd_add.rs index 7aa58b778b..4f225fd36c 100644 --- a/examples/simd/simd_add.rs +++ b/examples/simd/simd_add.rs @@ -33,7 +33,7 @@ fn simd_add_assign(xs: &mut Vec, ys: &Vec) { let p_y: *const f32 = ys.as_ptr(); // sum excess elements that don't fit in the simd vector - for i in range(4 * chunks, size) { + for i in (4 * chunks)..size { // dereferencing a raw pointer requires an unsafe block unsafe { // offset by i elements @@ -46,7 +46,7 @@ fn simd_add_assign(xs: &mut Vec, ys: &Vec) { let simd_p_y = p_y as *const f32x4; // sum "simd vector" - for i in range(0, chunks) { + for i in 0..chunks { unsafe { *simd_p_x.offset(i) += *simd_p_y.offset(i); } diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index d96809f846..05eea951a2 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,4 +1,3 @@ -#![feature(core)] #![feature(std_misc)] use std::thread::Thread; @@ -7,7 +6,7 @@ static NTHREADS: i32 = 10; // This is the `main` thread fn main() { - for i in range(0, NTHREADS) { + for i in 0..NTHREADS { // Spin up another thread let _ = Thread::scoped(move || { println!("this is thread number {}", i) diff --git a/examples/vec/vec.rs b/examples/vec/vec.rs index 3b6fe7c6fc..9747f5b628 100644 --- a/examples/vec/vec.rs +++ b/examples/vec/vec.rs @@ -1,7 +1,7 @@ fn main() { // Iterators can be collected into vectors - let collected_iterator: Vec = range(0, 10).collect(); - println!("Collected range(0, 10) into: {:?}", collected_iterator); + let collected_iterator: Vec = (0..10).collect(); + println!("Collected (0..10) into: {:?}", collected_iterator); // The `vec!` macro can be used to initialize a vector let mut xs = vec![1i32, 2, 3]; diff --git a/src/main.rs b/src/main.rs index 64e508a64c..8cc95eeebb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ fn main() { nexamples += count; } - let mut entries = range(0, nexamples).map(|_| { + let mut entries = (0..nexamples).map(|_| { rx.recv().unwrap() }).collect::, String)>>(); From 7294f670c47fdb09d4d00f74d0a701140b317402 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 12:50:02 -0500 Subject: [PATCH 0113/1122] Prevent unstyled content Fixes #300 --- node_modules/gitbook-plugin-rust-playpen/book/editor.css | 1 + 1 file changed, 1 insertion(+) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index 2d2806bcf2..4eee7e902e 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -17,6 +17,7 @@ min-height: 72px; font-size: 13px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + white-space: pre-wrap; } #result { From a65a44afd522ca81d5f2b31d10b0d40cc2b200d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Fri, 19 Dec 2014 10:13:49 +0100 Subject: [PATCH 0114/1122] Check links in *.md for 404 when `make test`ing. Fixes #249 --- Makefile | 1 + check-links.sh | 66 ++++++++++++++++++++++++++++++++++ examples/file/create/input.md | 6 ++-- examples/fs/input.md | 6 ++-- examples/hash/hashset/input.md | 4 +-- examples/path/input.md | 12 ++----- examples/trait/derive/input.md | 6 ++-- examples/type/alias/input.md | 6 ++-- 8 files changed, 79 insertions(+), 28 deletions(-) create mode 100755 check-links.sh diff --git a/Makefile b/Makefile index fbaa610f60..cf52e7f42c 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ clean: test: @$(foreach src,$(srcs),$(RUSTC_NT) $(src) || exit;) ./check-line-length.sh + ./check-links.sh serve: node_modules/gitbook $(GITBOOK) serve stage diff --git a/check-links.sh b/check-links.sh new file mode 100755 index 0000000000..9da1c2e9a3 --- /dev/null +++ b/check-links.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# +# Extract links from Markdown documents, and check +# their HTTP status. Flag anything that doesn't +# return a 200. +# + +DELIMITER="{{-%%-}}" + +echo "Checking links..." + +any_bad_links=false + +files=$(find ./examples -name "*.md") + +for file in $files ; do + + # + # Extract the urls, if any, along with the line numbers. + # + reference_style_links=$(grep -n "^\[[^]]\+\]:\ http" $file | \ + sed -e "s/:/$DELIMITER/" -e "s/\[[^]]*\]: //") + + inline_links=$(grep -no "\[[^]]\+\]([^[:space:]]\+)" $file | \ + sed -e "s/:/$DELIMITER/" -e "s/\[[^]]*\](//" -e "s/)$//") + + if [[ $reference_style_links == "" && $inline_links == "" ]]; then + continue + elif [[ $reference_style_links == "" ]]; then + all_links="$inline_links" + elif [[ $inline_links == "" ]]; then + all_links="$reference_style_links" + else + all_links=$(echo "$reference_style_links"$'\n'"$inline_links" | sort -n) + fi + + for link in $all_links ; do + + url=$(echo $link | awk -F"$DELIMITER" '{print $2}') + + # -s: silent + # -L: follow redirect + # -o: send output to /dev/null + # -I: load headers only + # -w: write the status code to stdout + status_code=$(curl -s -L -o /dev/null -I -w "%{http_code}" "$url") + + if [[ $status_code == "200" ]]; then + continue + fi + + any_bad_links=true + + line_number=$(echo $link | awk -F"$DELIMITER" '{print $1}') + + echo -e "Bad link in $file:$line_number [$status_code] $url" + done + +done + +if $any_bad_links; then + exit 1 +else + echo "All links are 200!" +fi \ No newline at end of file diff --git a/examples/file/create/input.md b/examples/file/create/input.md index 0452492503..462b030739 100644 --- a/examples/file/create/input.md +++ b/examples/file/create/input.md @@ -22,8 +22,6 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum. (As in the previous example, you are encouraged to test this example under failure conditions) -There is also a more generic -[`open_mode`][open-mode] -method that can open files in other modes like: read+write, append, etc. +There is also a more generic `open_mode` method that can open files in other +modes like: read+write, append, etc. -[open-mode]: http://doc.rust-lang.org/std/io/fs/struct.File.html#method.open_mode diff --git a/examples/fs/input.md b/examples/fs/input.md index 6ca8ff49a4..162d3ce765 100644 --- a/examples/fs/input.md +++ b/examples/fs/input.md @@ -1,5 +1,5 @@ -The [`std::io::fs`][std-fs] -module contains several functions that deal with the filesystem. +The `std::io::fs` module contains several functions that deal with the +filesystem. {fs.play} @@ -39,5 +39,3 @@ a 1 directory, 2 files ``` - -[std-fs]: http://doc.rust-lang.org/std/io/fs/ diff --git a/examples/hash/hashset/input.md b/examples/hash/hashset/input.md index 592628e026..e0055be940 100644 --- a/examples/hash/hashset/input.md +++ b/examples/hash/hashset/input.md @@ -6,7 +6,7 @@ Consider a `HashSet` as a `HashMap` where we just care about the keys ( A `HashSet`'s unique feature is that it is guaranteed to not have duplicate elements. That's the contract that any set collection fulfills. -`HashSet` is just one implementation. (see also: [`TreeSet`][treeset]) +`HashSet` is just one implementation. (see also: [`BTreeSet`][treeset]) If you insert a value that is already present in the `HashSet`, (i.e. the new value is equal to the existing and they both have the same hash), @@ -34,5 +34,5 @@ Try all of these in the following example. (Examples adapted from the [documentation.][hash-set]) -[treeset]: http://doc.rust-lang.org/std/collections/struct.TreeSet.html +[treeset]: http://doc.rust-lang.org/std/collections/struct.BTreeSet.html [hash-set]: http://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference diff --git a/examples/path/input.md b/examples/path/input.md index b6330a01db..1d95da93fc 100644 --- a/examples/path/input.md +++ b/examples/path/input.md @@ -13,13 +13,5 @@ instead is stored as a vector of bytes (`Vec`). Therefore, converting a {path.play} -Be sure to check at other `Path` methods -([`posix::Path`][posix-path] -or [`windows::Path`][windows-path]) -and the -[`FileStat`][file-stat] -struct. - -[posix-path]: http://doc.rust-lang.org/std/path/posix/struct.Path.html -[windows-path]: http://doc.rust-lang.org/std/path/windows/struct.Path.html -[file-stat]: http://doc.rust-lang.org/std/io/struct.FileStat.html +Be sure to check at other `Path` methods (`posix::Path` or `windows::Path`) and +the `FileStat` struct. diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index 6e3d45a9c8..f668d29ab0 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -17,11 +17,11 @@ This is a list of the "derivable" traits: to create `T` from `&T` via a copy. * [`Hash`][hash], to compute a hash from `&T`. -* [`Rand`][rand], to +* `Rand`, to create a random instance of a data type. * [`Default`][default], to create an empty instance of a data type. -* [`Zero`][zero], to +* `Zero`, to create a zero instance of a numeric data type. * [`FromPrimitive`][from-primitive], to create an instance from a numeric primitive. @@ -37,8 +37,6 @@ This is a list of the "derivable" traits: [decodable]: http://doc.rust-lang.org/serialize/trait.Decodable.html [clone]: http://doc.rust-lang.org/std/clone/trait.Clone.html [hash]: http://doc.rust-lang.org/std/hash/trait.Hash.html -[rand]: http://doc.rust-lang.org/rand/trait.Rand.html [default]: http://doc.rust-lang.org/std/default/trait.Default.html -[zero]: http://doc.rust-lang.org/std/num/trait.Zero.html [from-primitive]: http://doc.rust-lang.org/std/num/trait.FromPrimitive.html [debug]: http://doc.rust-lang.org/std/fmt/trait.Debug.html diff --git a/examples/type/alias/input.md b/examples/type/alias/input.md index 3647b0b79d..4cbacb952a 100644 --- a/examples/type/alias/input.md +++ b/examples/type/alias/input.md @@ -4,8 +4,6 @@ exception to this rule are the primitive types: `usize`, `f32`, etc. {alias.play} -The main use of aliases is to reduce typing; for example the -[`IoResult`][io-result] -type is an alias for the `Result` type. +The main use of aliases is to reduce typing; for example the `IoResult` type +is an alias for the `Result` type. -[io-result]: http://doc.rust-lang.org/std/io/type.IoResult.html From af2079ccb17b91039a86ec1000bd85ef5fdeb0c1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 14 Feb 2015 13:07:20 -0500 Subject: [PATCH 0115/1122] Don't use 'task' Fixes #358 --- examples/array/array.rs | 2 +- examples/constants/constants.rs | 2 +- examples/panic/input.md | 8 ++++---- examples/panic/panic.rs | 2 +- examples/threads/input.md | 6 +----- examples/timers/timers.rs | 2 +- examples/vec/vec.rs | 2 +- 7 files changed, 10 insertions(+), 14 deletions(-) diff --git a/examples/array/array.rs b/examples/array/array.rs index e8a1e1a300..17255f9467 100644 --- a/examples/array/array.rs +++ b/examples/array/array.rs @@ -31,6 +31,6 @@ fn main() { println!("borrow a section of the array as a slice"); analyze_slice(&ys[1 .. 4]); - // Out of bound indexing yields a task failure + // Out of bound indexing yields a panic println!("{}", xs[5]); } diff --git a/examples/constants/constants.rs b/examples/constants/constants.rs index dc8717643b..3cd3d93a94 100644 --- a/examples/constants/constants.rs +++ b/examples/constants/constants.rs @@ -9,7 +9,7 @@ fn is_big(n: i32) -> bool { fn main() { let n = 16; - // Access constant in the main task + // Access constant in the main thread println!("This is {}", LANGUAGE); println!("The threshold is {}", THRESHOLD); println!("{} is {}", n, if is_big(n) { "big" } else { "small" }); diff --git a/examples/panic/input.md b/examples/panic/input.md index a9241ad24c..a9f91b6321 100644 --- a/examples/panic/input.md +++ b/examples/panic/input.md @@ -1,8 +1,8 @@ -The `panic!` macro can be used to generate a *task* panic and start unwinding +The `panic!` macro can be used to generate a panic and start unwinding its stack. While unwinding, the runtime will take care of freeing all the -resources *owned* by the task by calling the destructor of all its objects. +resources *owned* by the thread by calling the destructor of all its objects. -Since we are dealing with programs with only one task, `panic!` will cause the +Since we are dealing with programs with only one thread, `panic!` will cause the program to report the panic message and exit. {panic.play} @@ -16,7 +16,7 @@ $ rustc panic.rs && valgrind ./panic ==4401== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==4401== Command: ./panic ==4401== -task '
' panicked at 'division by zero', panic.rs:5 +thread '
' panicked at 'division by zero', panic.rs:5 ==4401== ==4401== HEAP SUMMARY: ==4401== in use at exit: 0 bytes in 0 blocks diff --git a/examples/panic/panic.rs b/examples/panic/panic.rs index 37caae853d..f0e065de9c 100644 --- a/examples/panic/panic.rs +++ b/examples/panic/panic.rs @@ -3,7 +3,7 @@ // Re-implementation of integer division (/) fn division(dividend: i32, divisor: i32) -> i32 { if divisor == 0 { - // Division by zero triggers a task panic + // Division by zero triggers a panic panic!("division by zero"); } else { dividend / divisor diff --git a/examples/threads/input.md b/examples/threads/input.md index 6c8e1d05f2..a69d32e11b 100644 --- a/examples/threads/input.md +++ b/examples/threads/input.md @@ -3,8 +3,4 @@ function, the argument of this function is a moving closure. {threads.play} -These threads will be scheduled by the OS and the order of execution of -these tasks will be non-deterministic. - -(Currently Rust uses *native* runtime, which maps each Rust task to a -native thread.) +These threads will be scheduled by the OS. diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 0910f684c1..ea806a64b7 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -19,7 +19,7 @@ fn main() { println!("Wait {} ms...", interval.num_milliseconds()); - // Block the task until notification arrives + // Block the thread until notification arrives let _ = oneshot.recv(); println!("Done"); diff --git a/examples/vec/vec.rs b/examples/vec/vec.rs index 9747f5b628..afb6d7a8c9 100644 --- a/examples/vec/vec.rs +++ b/examples/vec/vec.rs @@ -25,6 +25,6 @@ fn main() { // `pop` removes the last element from the vector and returns it println!("Pop last element: {:?}", xs.pop()); - // Out of bounds indexing yields a task failure + // Out of bounds indexing yields a panic println!("Fourth element: {}", xs[3]); } From aa5999720774bde5e27e9849d9ad94a39eacc670 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 14 Feb 2015 14:43:35 -0500 Subject: [PATCH 0116/1122] Move all flow control items into `flow control` group. Add `if let`/`while let` explanations. Add destructuring pointers and enums add refs. Add guard binding on match --- examples/{ => flow_control}/for/for.rs | 0 examples/{ => flow_control}/for/input.md | 2 +- .../{ => flow_control}/if-else/if-else.rs | 0 examples/{ => flow_control}/if-else/input.md | 0 examples/flow_control/if_let/if_let.rs | 34 +++++++++++++ examples/flow_control/if_let/input.md | 30 +++++++++++ examples/flow_control/input.md | 3 ++ examples/{ => flow_control}/loop/input.md | 0 examples/{ => flow_control}/loop/loop.rs | 0 .../{ => flow_control}/loop/nested/input.md | 0 .../{ => flow_control}/loop/nested/nested.rs | 0 .../flow_control/match/binding/binding.rs | 13 +++++ examples/flow_control/match/binding/input.md | 3 ++ .../destructuring/destructure_enum/enum.rs | 30 +++++++++++ .../destructuring/destructure_enum/input.md | 10 ++++ .../destructure_pointers/input.md | 8 +++ .../destructure_pointers/pointers.rs | 50 +++++++++++++++++++ .../destructure_references/input.md | 9 ++++ .../destructure_references/ref.rs | 23 +++++++++ .../destructure_structures/input.md | 6 +++ .../destructure_structures}/struct.rs | 0 .../destructuring/destructure_tuple/input.md | 6 +++ .../destructuring/destructure_tuple/tuples.rs | 14 ++++++ .../flow_control/match/destructuring/input.md | 1 + .../{ => flow_control}/match/guard/guard.rs | 5 +- examples/flow_control/match/guard/input.md | 6 +++ examples/{ => flow_control}/match/input.md | 0 examples/{ => flow_control}/match/match.rs | 0 .../{ => flow_control}/match/struct/input.md | 3 ++ examples/flow_control/match/struct/struct.rs | 22 ++++++++ examples/{ => flow_control}/while/input.md | 0 examples/{ => flow_control}/while/while.rs | 0 examples/flow_control/while_let/input.md | 38 ++++++++++++++ examples/flow_control/while_let/while_let.rs | 20 ++++++++ examples/match/guard/input.md | 4 -- examples/structure.json | 28 +++++++---- 36 files changed, 350 insertions(+), 18 deletions(-) rename examples/{ => flow_control}/for/for.rs (100%) rename examples/{ => flow_control}/for/input.md (95%) rename examples/{ => flow_control}/if-else/if-else.rs (100%) rename examples/{ => flow_control}/if-else/input.md (100%) create mode 100644 examples/flow_control/if_let/if_let.rs create mode 100644 examples/flow_control/if_let/input.md create mode 100644 examples/flow_control/input.md rename examples/{ => flow_control}/loop/input.md (100%) rename examples/{ => flow_control}/loop/loop.rs (100%) rename examples/{ => flow_control}/loop/nested/input.md (100%) rename examples/{ => flow_control}/loop/nested/nested.rs (100%) create mode 100644 examples/flow_control/match/binding/binding.rs create mode 100644 examples/flow_control/match/binding/input.md create mode 100644 examples/flow_control/match/destructuring/destructure_enum/enum.rs create mode 100644 examples/flow_control/match/destructuring/destructure_enum/input.md create mode 100644 examples/flow_control/match/destructuring/destructure_pointers/input.md create mode 100644 examples/flow_control/match/destructuring/destructure_pointers/pointers.rs create mode 100644 examples/flow_control/match/destructuring/destructure_references/input.md create mode 100644 examples/flow_control/match/destructuring/destructure_references/ref.rs create mode 100644 examples/flow_control/match/destructuring/destructure_structures/input.md rename examples/{match/struct => flow_control/match/destructuring/destructure_structures}/struct.rs (100%) create mode 100644 examples/flow_control/match/destructuring/destructure_tuple/input.md create mode 100644 examples/flow_control/match/destructuring/destructure_tuple/tuples.rs create mode 100644 examples/flow_control/match/destructuring/input.md rename examples/{ => flow_control}/match/guard/guard.rs (71%) create mode 100644 examples/flow_control/match/guard/input.md rename examples/{ => flow_control}/match/input.md (100%) rename examples/{ => flow_control}/match/match.rs (100%) rename examples/{ => flow_control}/match/struct/input.md (63%) create mode 100644 examples/flow_control/match/struct/struct.rs rename examples/{ => flow_control}/while/input.md (100%) rename examples/{ => flow_control}/while/while.rs (100%) create mode 100644 examples/flow_control/while_let/input.md create mode 100644 examples/flow_control/while_let/while_let.rs delete mode 100644 examples/match/guard/input.md diff --git a/examples/for/for.rs b/examples/flow_control/for/for.rs similarity index 100% rename from examples/for/for.rs rename to examples/flow_control/for/for.rs diff --git a/examples/for/input.md b/examples/flow_control/for/input.md similarity index 95% rename from examples/for/input.md rename to examples/flow_control/for/input.md index de6f516723..0db1a884c0 100644 --- a/examples/for/input.md +++ b/examples/flow_control/for/input.md @@ -1,6 +1,6 @@ The `for in` construct can be used to iterate an `Iterator`, a lazy value generator (more details later). One of the easiest ways to create an iterator -is to use the range notation. `a..b` will yield values from `a` (inclusive) to +is to use the range notation. `a..b` will yield values from `a` (inclusive) to `b` (exclusive) in steps of one. Let's write FizzBuzz using `for` instead of `while`. diff --git a/examples/if-else/if-else.rs b/examples/flow_control/if-else/if-else.rs similarity index 100% rename from examples/if-else/if-else.rs rename to examples/flow_control/if-else/if-else.rs diff --git a/examples/if-else/input.md b/examples/flow_control/if-else/input.md similarity index 100% rename from examples/if-else/input.md rename to examples/flow_control/if-else/input.md diff --git a/examples/flow_control/if_let/if_let.rs b/examples/flow_control/if_let/if_let.rs new file mode 100644 index 0000000000..eb96cb6c42 --- /dev/null +++ b/examples/flow_control/if_let/if_let.rs @@ -0,0 +1,34 @@ +fn main() { + // All have type `Option` + let number = Some(7); + let letter: Option = None; + let emoticon: Option = None; + + // The `if let` construct reads: "if `let` destructures `number` into + // `Some(i)`, evaluate the block (`{}`). Else do nothing. + if let Some(i) = number { + println!("Matched {:?}!", i); + } + + // If you need to specify a failure, use an else: + if let Some(i) = letter { + println!("Matched {:?}!", i); + } else { + // Destructure failed. Change the failure case. + println!("Didn't match a number. Let's go with a letter!"); + }; + + // Provide an altered failing condition. + let i_like_letters = false; + + if let Some(i) = emoticon { + println!("Matched {:?}!", i); + // Destructure failed. Evaluated the condition to see if this branch + // should be taken. + } else if i_like_letters { + println!("Didn't match a number. Let's go with a letter!"); + // The condition evaluated false. This branch is the default. + } else { + println!("I don't like letters. Let's go with an emoticon :)!"); + }; +} diff --git a/examples/flow_control/if_let/input.md b/examples/flow_control/if_let/input.md new file mode 100644 index 0000000000..c17fc3ad6b --- /dev/null +++ b/examples/flow_control/if_let/input.md @@ -0,0 +1,30 @@ +For some use cases, `match` is awkward. For example: + +```rust +// Make `optional` of type `Option` +let optional = Some(7); + +match optional { + Some(i) => { + println!("This is a really long string and `{:?}`", i); + // ^ Needed 2 indentations just so we could destructure + // `i` from the option. + }, + _ => {}, + // ^ Required because `match` is exhaustive. Doesn't it seem + // like wasted space? +}; + +``` + +`if let` is cleaner for this use case and in addition allows various +failure options to be specified: + +{if_let.play} + +### See also: +[`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] + +[enum]: /enum.html +[if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 +[option]: /option.html diff --git a/examples/flow_control/input.md b/examples/flow_control/input.md new file mode 100644 index 0000000000..d846bfd76c --- /dev/null +++ b/examples/flow_control/input.md @@ -0,0 +1,3 @@ +Here we will analyze various flow control structures such as +`if`/`else`, `for` and the related `i..j` notation, `while`, +`loop`, `match` and the related `if let` and `while let` simplifications. diff --git a/examples/loop/input.md b/examples/flow_control/loop/input.md similarity index 100% rename from examples/loop/input.md rename to examples/flow_control/loop/input.md diff --git a/examples/loop/loop.rs b/examples/flow_control/loop/loop.rs similarity index 100% rename from examples/loop/loop.rs rename to examples/flow_control/loop/loop.rs diff --git a/examples/loop/nested/input.md b/examples/flow_control/loop/nested/input.md similarity index 100% rename from examples/loop/nested/input.md rename to examples/flow_control/loop/nested/input.md diff --git a/examples/loop/nested/nested.rs b/examples/flow_control/loop/nested/nested.rs similarity index 100% rename from examples/loop/nested/nested.rs rename to examples/flow_control/loop/nested/nested.rs diff --git a/examples/flow_control/match/binding/binding.rs b/examples/flow_control/match/binding/binding.rs new file mode 100644 index 0000000000..d7dcb86986 --- /dev/null +++ b/examples/flow_control/match/binding/binding.rs @@ -0,0 +1,13 @@ +fn main() { + let age = 3; + // TODO ^ Try different values for `age` + + println!("Tell me type of person you are"); + match age { + // Bind to `n` for the sequence of 1 through 12. + n @ 1 ... 12 => println!("I'm a child of age {:?}", n), + n @ 13 ... 19 => println!("I'm a teen of age {:?}", n), + // Nothing bound. Return the result. + n => println!("I'm an old person of age {:?}", n), + } +} diff --git a/examples/flow_control/match/binding/input.md b/examples/flow_control/match/binding/input.md new file mode 100644 index 0000000000..28b9839ffa --- /dev/null +++ b/examples/flow_control/match/binding/input.md @@ -0,0 +1,3 @@ +Rust supports binding variables via a `match`: + +{binding.play} diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs new file mode 100644 index 0000000000..1ca47109d6 --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_enum/enum.rs @@ -0,0 +1,30 @@ +// Must derive `Debug` so `println!` can be used. +// `allow` required to silence warnings because only +// one variant is used. +#[allow(dead_code)] +#[derive(Debug)] +enum Color { + // These 3 are specified solely by their name. + Red, + Blue, + Green, + // This requires 3 `i32`s and a name. + RGB(i32, i32, i32), +} + +fn main() { + let color = Color::RGB(122, 17, 40); + // TODO ^ Try different variants for `color` + + println!("What color is it?"); + // An `enum` can be destructured using a `match`. + match color { + Color::Red => println!("The color is Red!"), + Color::Blue => println!("The color is Blue!"), + Color::Green => println!("The color is Green!"), + Color::RGB(r, g, b) => { + println!("Red: {:?}, green: {:?}, and blue: {:?}!:", r, g, b); + }, + // Don't need another arm because all variants have been examined + } +} diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md new file mode 100644 index 0000000000..14e9407e20 --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -0,0 +1,10 @@ +An `enum` is destructured similarly: + +{enum.play} + +### See also: +[`#[allow(...)]`][allow], [`enum`][enum], and [`#[derive(...)]`][derive] + +[enum]: /enum.html +[derive]: /trait/derive.html +[allow]: /fn/unused.html diff --git a/examples/flow_control/match/destructuring/destructure_pointers/input.md b/examples/flow_control/match/destructuring/destructure_pointers/input.md new file mode 100644 index 0000000000..a7373ad8d2 --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_pointers/input.md @@ -0,0 +1,8 @@ +For pointers, a distinction needs to be made between destructuring +and dereferencing as they are different concepts which are used +differently from a language like `C`. + + * Dereferencing uses `*` + * Destructuring uses `&`, `ref`, and `ref mut` + +{pointers.play} diff --git a/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs b/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs new file mode 100644 index 0000000000..9bef33c1da --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs @@ -0,0 +1,50 @@ +fn main() { + // Assign a reference of type `i32`. The `&` signifies there + // is a reference being assigned. + let reference = &4; + + match reference { + // If `reference`s is pattern matched against `&val`, it results + // in a comparison like: + // `&i32` + // `&val` + // ^ We see that if the matching `&`s are dropped, then the `i32` + // should be assigned to `val`. + &val => println!("Got a value via destructuring: {:?}", val), + } + + // To avoid the `&`, you dereference before matching. + match *reference { + val => println!("Got a value via dereferencing: {:?}", val), + } + + // What if you don't start with a reference? `reference` was a `&` + // because the right side was already a reference. This is not + // a reference because the right side is not one. + let _not_a_reference = 3; + + // Rust provides `ref` for exacty this purpose. It modifies the + // assignment so that a reference is created for the element; this + // reference is assigned. + let ref _is_a_reference = 3; + + // Accordingly, by defining 2 values without references, references + // can be retrieved via `ref` and `ref mut`. + let value = 5; + let mut mut_value = 6; + + // Use `ref` keyword to create a reference. + match value { + ref r => println!("Got a reference to a value: {:?}", r), + } + + // Use `ref mut` similarly. + match mut_value { + ref mut m => { + // Got a reference. Gotta dereference it before we can + // add anything to it. + *m += 10; + println!("We added 10. `mut_value`: {:?}", m); + }, + } +} diff --git a/examples/flow_control/match/destructuring/destructure_references/input.md b/examples/flow_control/match/destructuring/destructure_references/input.md new file mode 100644 index 0000000000..a74ba8dbfb --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_references/input.md @@ -0,0 +1,9 @@ +References and mutable references can be retrieved via +`ref` and `ref mut`: + +{ref.play} + +### See also: +[Borrowing (`&`)][borrow] + +[borrow]: /borrow.html diff --git a/examples/flow_control/match/destructuring/destructure_references/ref.rs b/examples/flow_control/match/destructuring/destructure_references/ref.rs new file mode 100644 index 0000000000..0ba0a72543 --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_references/ref.rs @@ -0,0 +1,23 @@ +fn main() { + // Start with two regular values + let value = 5; + let mut mut_value = 6; + + // To destructure into `&5` (reference to 5), use the `ref` keyword. + match value { + // `println!` can handle both regular values and references + // so it doesn't care which we give it. `r` will have type `&i32`. + ref r => println!("Got a reference to a value: {:?}", r), + } + + // Likewise, to get a mutable reference `&mut 6` back, + // `ref mut` is used. + match mut_value { + ref mut m => { + // Got a reference. Gotta dereference it before we can + // add anything to it. + *m += 10; + println!("We added 10. `mut_value`: {:?}", m); + }, + } +} diff --git a/examples/flow_control/match/destructuring/destructure_structures/input.md b/examples/flow_control/match/destructuring/destructure_structures/input.md new file mode 100644 index 0000000000..634e7883ab --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_structures/input.md @@ -0,0 +1,6 @@ +Similarly, a `struct` can be destructured as shown: + +{struct.play} + +### See also: +[Structs](/structs.html) diff --git a/examples/match/struct/struct.rs b/examples/flow_control/match/destructuring/destructure_structures/struct.rs similarity index 100% rename from examples/match/struct/struct.rs rename to examples/flow_control/match/destructuring/destructure_structures/struct.rs diff --git a/examples/flow_control/match/destructuring/destructure_tuple/input.md b/examples/flow_control/match/destructuring/destructure_tuple/input.md new file mode 100644 index 0000000000..c3943b7a5e --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_tuple/input.md @@ -0,0 +1,6 @@ +Tuples can be destructured in a `match` as follows: + +{tuples.play} + +### See also: +[Tuples](/tuples.html) diff --git a/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs b/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs new file mode 100644 index 0000000000..ab27884ca5 --- /dev/null +++ b/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs @@ -0,0 +1,14 @@ +fn main() { + let pair = (0, -2); + // TODO ^ Try different values for `pair` + + println!("Tell me about {:?}", pair); + // Match can be used to destructure a tuple + match pair { + // Destructure the second + (0, y) => println!("First is `0` and `y` is `{:?}`", y), + (x, 0) => println!("`x` is `{:?}` and last is `0`", x), + _ => println!("It doesn't matter what they are"), + // `_` means don't bind the value to a variable + } +} diff --git a/examples/flow_control/match/destructuring/input.md b/examples/flow_control/match/destructuring/input.md new file mode 100644 index 0000000000..c86edcb071 --- /dev/null +++ b/examples/flow_control/match/destructuring/input.md @@ -0,0 +1 @@ +A `match` block can destructure items in a variety of ways. diff --git a/examples/match/guard/guard.rs b/examples/flow_control/match/guard/guard.rs similarity index 71% rename from examples/match/guard/guard.rs rename to examples/flow_control/match/guard/guard.rs index 72e8e03336..f246e4a0b2 100644 --- a/examples/match/guard/guard.rs +++ b/examples/flow_control/match/guard/guard.rs @@ -1,15 +1,12 @@ fn main() { - let pair = (2i32, -2); + let pair = (2, -2); // TODO ^ Try different values for `pair` println!("Tell me about {:?}", pair); - // Match can be used to destructure a tuple match pair { - // Destructure the tuple (x, y) if x == y => println!("These are twins"), // The ^ `if condition` part is a guard (x, y) if x + y == 0 => println!("Antimatter, kaboom!"), - // `_` means don't bind the value to a variable (x, _) if x % 2 == 1 => println!("The first one is odd"), _ => println!("No correlation..."), } diff --git a/examples/flow_control/match/guard/input.md b/examples/flow_control/match/guard/input.md new file mode 100644 index 0000000000..3bf630622d --- /dev/null +++ b/examples/flow_control/match/guard/input.md @@ -0,0 +1,6 @@ +A `match` *guard* can be added to filter the arm. + +{guard.play} + +### See also: +[Tuples](/tuples.html) diff --git a/examples/match/input.md b/examples/flow_control/match/input.md similarity index 100% rename from examples/match/input.md rename to examples/flow_control/match/input.md diff --git a/examples/match/match.rs b/examples/flow_control/match/match.rs similarity index 100% rename from examples/match/match.rs rename to examples/flow_control/match/match.rs diff --git a/examples/match/struct/input.md b/examples/flow_control/match/struct/input.md similarity index 63% rename from examples/match/struct/input.md rename to examples/flow_control/match/struct/input.md index a9e6b3b7d1..9c405ce7a7 100644 --- a/examples/match/struct/input.md +++ b/examples/flow_control/match/struct/input.md @@ -1,3 +1,6 @@ A `struct` can be destructured with pattern matching. {struct.play} + +### See also: +[Structs](/structs.html) diff --git a/examples/flow_control/match/struct/struct.rs b/examples/flow_control/match/struct/struct.rs new file mode 100644 index 0000000000..224f583deb --- /dev/null +++ b/examples/flow_control/match/struct/struct.rs @@ -0,0 +1,22 @@ +fn main() { + struct Foo { x: (u32, u32), y: u32 } + + // destructure members of the struct + let foo = Foo { x: (1, 2), y: 3 }; + let Foo { x: (a, b), y } = foo; + + println!("a = {}, b = {}, y = {} ", a, b, y); + + // you can destructure structs and rename the variables, + // the order is not important + + let Foo { y: i, x: j } = foo; + println!("i = {:?}, j = {:?}", i, j); + + // and you can also ignore some variables: + let Foo { y, .. } = foo; + println!("y = {}", y); + + // this will give an error: pattern does not mention field `x` + // let Foo { y } = foo; +} diff --git a/examples/while/input.md b/examples/flow_control/while/input.md similarity index 100% rename from examples/while/input.md rename to examples/flow_control/while/input.md diff --git a/examples/while/while.rs b/examples/flow_control/while/while.rs similarity index 100% rename from examples/while/while.rs rename to examples/flow_control/while/while.rs diff --git a/examples/flow_control/while_let/input.md b/examples/flow_control/while_let/input.md new file mode 100644 index 0000000000..89eccb7b64 --- /dev/null +++ b/examples/flow_control/while_let/input.md @@ -0,0 +1,38 @@ +Similar to `if let`, `while let` can make awkward `match` sequences +more tolerable. Consider, for example the following sequence: + +```rust +// Make `optional` of type `Option` +let mut optional = Some(0); + +// Repeatedly try this test. +loop { + match optional { + // If `optional` destructures, evaluate the block. + Some(i) => { + if i > 9 { + println!("Greater than 9, quit!"); + optional = None; + } else { + println!("`i` is `{:?}`. Try again.", i); + optional = Some(i + 1); + } + // ^ Requires 3 indentations! + }, + // Quit when the destructure fails, meaning `break`. + _ => { break; } + // ^ Why should this be required? Seems superfluous. + } +} +``` + +`while let` makes this sequence much nicer: + +{while_let.play} + +### See also: +[`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] + +[enum]: /enum.html +[option]: /option.html +[while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 diff --git a/examples/flow_control/while_let/while_let.rs b/examples/flow_control/while_let/while_let.rs new file mode 100644 index 0000000000..e2c11b4d00 --- /dev/null +++ b/examples/flow_control/while_let/while_let.rs @@ -0,0 +1,20 @@ +fn main() { + // Make `optional` of type `Option` + let mut optional = Some(0); + + // This reads: "while `let` destructures `optional` into + // `Some(i)`, evaluate the block (`{}`). Else `break`. + while let Some(i) = optional { + if i > 9 { + println!("Greater than 9, quit!"); + optional = None; + } else { + println!("`i` is `{:?}`. Try again.", i); + optional = Some(i + 1); + } + // ^ Less rightward drift and doesn't require + // explicitly handling the failing case. + } + // ^ `if let` had additional optional `else`/`else if` + // clauses. `while let` does not have these. +} diff --git a/examples/match/guard/input.md b/examples/match/guard/input.md deleted file mode 100644 index 8803a7b274..0000000000 --- a/examples/match/guard/input.md +++ /dev/null @@ -1,4 +0,0 @@ -The arms of a `match` block can be destructured, and a *guard* can be added to -further filter the arm. - -{guard.play} diff --git a/examples/structure.json b/examples/structure.json index 748ba808dd..9c35f8b67e 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -14,12 +14,26 @@ { "id": "alias", "title": "Alias", "children": null } ] }, { "id": "expression", "title": "Expressions", "children": null }, - { "id": "if-else", "title": "If/else", "children": null }, - { "id": "loop", "title": "Loop", "children": [ - { "id": "nested", "title": "Nesting and labels", "children": null } + { "id": "flow_control", "title": "Flow Control", "children": [ + { "id": "if-else", "title": "if/else", "children": null }, + { "id": "loop", "title": "loop", "children": [ + { "id": "nested", "title": "Nesting and labels", "children": null } + ] }, + { "id": "while", "title": "while", "children": null }, + { "id": "for", "title": "for and range", "children": null }, + { "id": "match", "title": "match", "children": [ + { "id": "destructuring", "title": "Destructuring", "children": [ + { "id": "destructure_tuple", "title": "tuples", "children": null }, + { "id": "destructure_enum", "title": "enums", "children": null }, + { "id": "destructure_pointers", "title": "pointers/ref", "children": null }, + { "id": "destructure_structures", "title": "structs", "children": null } + ] }, + { "id": "guard", "title": "Guards", "children": null }, + { "id": "binding", "title": "Binding", "children": null } + ] }, + { "id": "if_let", "title": "if let", "children": null }, + { "id": "while_let", "title": "while let", "children": null } ] }, - { "id": "while", "title": "While", "children": null }, - { "id": "for", "title": "For and range", "children": null }, { "id": "fn", "title": "Functions", "children": [ { "id": "unused", "title": "Unused", "children": null } ] }, @@ -40,10 +54,6 @@ ] } ] }, { "id": "tuples", "title": "Tuples", "children": null }, - { "id": "match", "title": "Pattern matching", "children": [ - { "id": "guard", "title": "Destructuring and guards", "children": null }, - { "id": "struct", "title": "Destructuring structs", "children": null } - ] }, { "id": "structs", "title": "Structures", "children": [ { "id": "visibility", "title": "Visibility", "children": null } ] }, From ebe10a83c97bb6e7db75509fe408909b3fd86805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Dre=CC=81au?= Date: Sun, 15 Feb 2015 00:56:05 +0100 Subject: [PATCH 0117/1122] Add relative/local link testing to the link checker --- check-links.sh | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/check-links.sh b/check-links.sh index 9da1c2e9a3..9b8e3783e1 100755 --- a/check-links.sh +++ b/check-links.sh @@ -39,15 +39,43 @@ for file in $files ; do url=$(echo $link | awk -F"$DELIMITER" '{print $2}') - # -s: silent - # -L: follow redirect - # -o: send output to /dev/null - # -I: load headers only - # -w: write the status code to stdout - status_code=$(curl -s -L -o /dev/null -I -w "%{http_code}" "$url") + # Check relative, internal, urls + if [[ ! $url == http://* ]] && [[ ! $url == https://* ]]; then + + local_path=$url + + # Remove the .html if present + if [[ $local_path == *.html ]]; then + local_path=${local_path:0:${#local_path}-5} + fi + + # Build the local directory path + # This depends on the GitBook style directory structure + if [[ ! $local_path == /* ]]; then + local_path="./examples/$local_path" + else + local_path="./examples$local_path" + fi + + if [[ -d $local_path ]]; then + continue + fi + + status_code="404" + + # Check external urls + else + + # -s: silent + # -L: follow redirect + # -o: send output to /dev/null + # -I: load headers only + # -w: write the status code to stdout + status_code=$(curl -s -L -o /dev/null -I -w "%{http_code}" "$url") - if [[ $status_code == "200" ]]; then - continue + if [[ $status_code == "200" ]]; then + continue + fi fi any_bad_links=true From 82f1c24e58f72e832450bba7b0143ff5f93d1a5b Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:00:02 +0000 Subject: [PATCH 0118/1122] array: Fix typo. --- examples/array/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/array/input.md b/examples/array/input.md index 45c14702b4..61a4f84a42 100644 --- a/examples/array/input.md +++ b/examples/array/input.md @@ -3,7 +3,7 @@ memory. Arrays are created using brackets `[]`, and their size, which is known at compile time, is part of their type signature `[T; size]`. Slices are similar to arrays, but their size is not known at compile time. -Instead, a slice is two-word object, the first word is a pointer to the data, +Instead, a slice is a two-word object, the first word is a pointer to the data, and the second word is the length of the slice. Slices can be used to borrow a section of an array, and have `&[T]` as type signature. From 56f7c56afda74967be0b03ae6f4bff67c0550b7f Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:01:49 +0000 Subject: [PATCH 0119/1122] array: small grammatical fix. --- examples/array/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/array/input.md b/examples/array/input.md index 61a4f84a42..48e27d682f 100644 --- a/examples/array/input.md +++ b/examples/array/input.md @@ -5,6 +5,6 @@ at compile time, is part of their type signature `[T; size]`. Slices are similar to arrays, but their size is not known at compile time. Instead, a slice is a two-word object, the first word is a pointer to the data, and the second word is the length of the slice. Slices can be used to borrow a -section of an array, and have `&[T]` as type signature. +section of an array, and have the type signature `&[T]`. {array.play} From 19a3604658a487b69b7a9fd47f0c4d667ed3adfa Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:04:32 +0000 Subject: [PATCH 0120/1122] hof: fix typo. --- examples/hof/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hof/input.md b/examples/hof/input.md index 2183b618d9..644846e7a0 100644 --- a/examples/hof/input.md +++ b/examples/hof/input.md @@ -1,6 +1,6 @@ Rust provides Higher Order Functions (HOF), these are functions that take a -closure as argument to produce a more useful function. HOFs and lazy iterators -give Rust its functional flavor. +closure as an argument to produce a more useful function. HOFs and lazy +iterators give Rust its functional flavor. {hof.play} From ce299144efe48a248ffde6796d6dd5e34f0c88b0 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:07:48 +0000 Subject: [PATCH 0121/1122] channels: fix typo in code comment. --- examples/channels/channels.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index 45bd9cff1f..a179418058 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -8,7 +8,7 @@ static NTHREADS: usize = 3; fn main() { // Channels have two endpoints: the `Sender` and the `Receiver`, - // where `T` is the type of the message to be transfer + // where `T` is the type of the message to be transferred // (type annotation is superfluous) let (tx, rx): (Sender, Receiver) = mpsc::channel(); From 481b2f854efd080e395ad2352e93aeddf924ece0 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:09:48 +0000 Subject: [PATCH 0122/1122] timers: fix typo. --- examples/timers/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/timers/input.md b/examples/timers/input.md index 1cf24cd382..4221014f92 100644 --- a/examples/timers/input.md +++ b/examples/timers/input.md @@ -4,7 +4,7 @@ A `Timer` represents an underlying OS timer, and can generate *one-shot* and {timers.play} The playpen has a time limit, so you won't be able to see the (full) output in -the editor. Here's the output you should see, if you run this in a computer. +the editor. Here's the output you should see, if you run this on a computer. ``` $ rustc timers.rs && time ./timers From 82683e9d19cfc747af9928b678209e84b776af30 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:11:42 +0000 Subject: [PATCH 0123/1122] result: fixed typo. --- examples/result/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/result/input.md b/examples/result/input.md index 5a8edab985..355af9334a 100644 --- a/examples/result/input.md +++ b/examples/result/input.md @@ -1,7 +1,7 @@ We've seen that the `Option` enum can be used as a return value from functions that may fail, where `None` can be returned to indicate failure. However, -sometimes is important to express *why* an operation failed. To do this we have -the `Result` enum. +sometimes it is important to express *why* an operation failed. To do this we +have the `Result` enum. The `Result` enum has two variants: From f12e938c0770268682e0bf97f28c6365bfd32cd0 Mon Sep 17 00:00:00 2001 From: yukipyon Date: Sun, 15 Feb 2015 11:14:25 +0000 Subject: [PATCH 0124/1122] file/open: fixed typos. --- examples/file/open/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/file/open/input.md b/examples/file/open/input.md index 8200b3a5bc..e065978b8e 100644 --- a/examples/file/open/input.md +++ b/examples/file/open/input.md @@ -1,7 +1,7 @@ The `open` static method can be used to open a file in read-only mode. -A `File` owns a resource, the file descriptor, and take cares of closing the -file when its `drop`ed. +A `File` owns a resource, the file descriptor and takes care of closing the +file when it is `drop`ed. {open.play} From 2599b1546d066f0e31d5862521998b102f922743 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Mon, 16 Feb 2015 12:23:16 +0200 Subject: [PATCH 0125/1122] Remove redundant into_iter() --- examples/str/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/str/str.rs b/examples/str/str.rs index 2cfbd660d5..c752c61181 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -20,7 +20,7 @@ fn main() { // Create an empty and growable `String` let mut string = String::new(); - for c in chars.into_iter() { + for c in chars { // Insert a char at the end of string string.push(c); // Insert a string at the end of string From 3720514ab70a219152ebc7297f2462b47cdb07c8 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 19 Feb 2015 11:42:30 -0500 Subject: [PATCH 0126/1122] Add in new feature gate --- examples/str/str.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/str/str.rs b/examples/str/str.rs index c752c61181..55627b1d95 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -1,5 +1,6 @@ #![feature(collections)] #![feature(core)] +#![feature(str_words)] fn main() { // (all the type annotations are superfluous) From 5b3c4004ebdb34a94a736d3ae53e2b04993b3b60 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 19 Feb 2015 12:56:41 -0500 Subject: [PATCH 0127/1122] Update dependencies and fix the build. --- Cargo.lock | 4 ++-- examples/channels/channels.rs | 4 ++-- examples/threads/threads.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc095b4b4c..54a263c108 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index a179418058..d82471ba64 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -2,7 +2,7 @@ use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use std::thread::Thread; +use std::thread; static NTHREADS: usize = 3; @@ -17,7 +17,7 @@ fn main() { let thread_tx = tx.clone(); // Each thread will send its id via the channel - Thread::spawn(move || { + thread::spawn(move || { // The thread takes ownership over `thread_tx` // Each thread queues a message in the channel thread_tx.send(id).unwrap(); diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index 05eea951a2..ad9ff18d49 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,6 +1,6 @@ #![feature(std_misc)] -use std::thread::Thread; +use std::thread; static NTHREADS: i32 = 10; @@ -8,7 +8,7 @@ static NTHREADS: i32 = 10; fn main() { for i in 0..NTHREADS { // Spin up another thread - let _ = Thread::scoped(move || { + let _ = thread::scoped(move || { println!("this is thread number {}", i) }); } From 7e4f9755a25030bea75efb782763b88f5e85998f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 19 Feb 2015 13:10:19 -0500 Subject: [PATCH 0128/1122] update travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 839b2c0fde..8a3c73a10a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js install: - - curl -s https://static.rust-lang.org/rustup.sh | sudo sh > /dev/null + - curl -L -s https://static.rust-lang.org/rustup.sh | sudo sh > /dev/null script: - rustc --version From 59b714a96d996f17db8324214c70ae39b47295b8 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 20 Feb 2015 12:47:21 -0500 Subject: [PATCH 0129/1122] turn on sudo on travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8a3c73a10a..840fd4a9c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: node_js +sudo: true + install: - curl -L -s https://static.rust-lang.org/rustup.sh | sudo sh > /dev/null From 6d2893057228e3216dcf5372193fb507528faa68 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 20 Feb 2015 13:13:44 -0500 Subject: [PATCH 0130/1122] update regex --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54a263c108..628f5f4285 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" From aa6b7f3e8e416dd12918404c94888c3ce62cae37 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 20 Feb 2015 13:14:38 -0500 Subject: [PATCH 0131/1122] Fix the build --- src/main.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8cc95eeebb..4debc39966 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ #![feature(env)] -#![feature(io)] -#![feature(std_misc)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] #![feature(core)] #![deny(warnings)] @@ -13,7 +12,7 @@ extern crate regex; extern crate "rustc-serialize" as rustc_serialize; use example::Example; -use std::thread::Thread; +use std::thread; use std::sync::mpsc; mod example; @@ -30,7 +29,7 @@ fn main() { let tx = tx.clone(); let count = example.count(); - let _ = Thread::scoped(move || { + let _ = thread::scoped(move || { example.process(vec!(i + 1), tx, 0, String::new()); }); From 4f07383784b5db3e8122c4cc8b2890e132b7e1ec Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 20 Feb 2015 13:42:26 -0500 Subject: [PATCH 0132/1122] Phantom upgrade --- examples/generics/phantom/phantom.rs | 20 ++++++++++++++------ examples/generics/phantom/units/units.rs | 17 +++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs index a2f0f702c8..9c7d5d859c 100644 --- a/examples/generics/phantom/phantom.rs +++ b/examples/generics/phantom/phantom.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + // Generic tuplestruct with same types in both // generic and definition (A,) struct Tuple(A,); @@ -6,12 +8,12 @@ struct Tuple(A,); // parameter. Storage is allocated for generic type A // yet not for B. Therefore, B cannot be used in computations. #[derive(PartialEq)] // Allow equality test for this type -struct PhantomTuple(A,); +struct PhantomTuple(A,PhantomData); // Similarly, a phantom type struct which is generic over A // with hidden parameter B #[derive(PartialEq)] // Allow equality test for this type -struct PhantomStruct { first: A } +struct PhantomStruct { first: A, phantom: PhantomData } fn main() { // instantiate Tuple @@ -19,18 +21,24 @@ fn main() { // We can create similar types without carrying around extra info // PhantomTuple specialized to - let _tuple1: PhantomTuple = PhantomTuple('Q'); + let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); // PhantomTuple specialized to - let _tuple2: PhantomTuple = PhantomTuple('Q'); + let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); // Error: type mismatch so these cannot be compared //println!("_tuple1 == _tuple2 yields: {}", // _tuple1 == _tuple2); // Specialized to - let _struct1: PhantomStruct = PhantomStruct { first: 'Q'}; + let _struct1: PhantomStruct = PhantomStruct { + first: 'Q', + phantom: PhantomData, + }; // Specialized to - let _struct2: PhantomStruct = PhantomStruct { first: 'Q'}; + let _struct2: PhantomStruct = PhantomStruct { + first: 'Q', + phantom: PhantomData, + }; // Error: type mismatch so these cannot be compared //println!("_struct1 == _struct2 yields: {}", diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index 2406c44b2f..df2d1a91f1 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -1,4 +1,5 @@ use std::ops::Add; +use std::marker::PhantomData; /// Null enumerations to define unit types #[derive(Debug, Copy)] @@ -8,7 +9,7 @@ struct Mm; /// Length is phantom type with hidden parameter `Unit` #[derive(Debug, Copy)] -struct Length(T,); +struct Length(T,PhantomData); /// impl X for Y {} means "implement the trait `X` for the Type `Y`" /// The following lines implement the `Add` trait for Length. @@ -23,29 +24,29 @@ struct Length(T,); /// (meaning an i32 plus an i32, or an f64 plus an f64, etc.), and giving /// back a T (i32 + i32 = i32). /// -/// So, this impl implements `Add` for `Length`, +/// So, this impl implements `Add` for `Length`, /// which means you can add a `Length` to another `Length` of the same type. /// /// `type Output = Length` means that this impl gives back a -/// `Length`, so that +/// `Length`, so that /// `Length + Length = Length` impl + Copy> Add> for Length { type Output = Length; fn add(self, r: Length) -> Length { - let Length(ref left) = self; - let Length(ref right) = r; + let Length(ref left, _) = self; + let Length(ref right, _) = r; - Length(*left + *right) + Length(*left + *right, PhantomData) } } fn main() { // Specialize one_foot to have hidden parameter `Inch` - let one_foot: Length = Length(12.0); + let one_foot: Length = Length(12.0, PhantomData); // one_meter has hidden parameter `Mm` - let one_meter: Length = Length(1000.0); + let one_meter: Length = Length(1000.0, PhantomData); let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; From c5f1d5d62b118096d5f3c4f9cb5b72ba7e686505 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 11:01:15 -0500 Subject: [PATCH 0133/1122] Pin gitbook version so we don't get 2.0 https://twitter.com/steveklabnik/status/570255057477894147 Fixes #469 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cf52e7f42c..2ea5c54ed1 100644 --- a/Makefile +++ b/Makefile @@ -45,4 +45,4 @@ serve: node_modules/gitbook $(GITBOOK) serve stage node_modules/gitbook: - npm install gitbook + npm install gitbook@1.5.0 From 9483eff447bd4d8db89f01bc9ca89bc4ae582358 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 11:35:53 -0500 Subject: [PATCH 0134/1122] Don't fail the build for broken links The problem with this is that if anything we point to has an intermittent issue, we can't deploy. So make this a warning rather than a failure. --- check-links.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-links.sh b/check-links.sh index 9b8e3783e1..2579f03a51 100755 --- a/check-links.sh +++ b/check-links.sh @@ -88,7 +88,7 @@ for file in $files ; do done if $any_bad_links; then - exit 1 + echo "Some links were bad." else echo "All links are 200!" -fi \ No newline at end of file +fi From 1a5113f401f2e6539233a1eabcbdfba15dc24c22 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 12:23:08 -0500 Subject: [PATCH 0135/1122] Clean up feature gates. They've changed in the past few days, these are the new ones. --- examples/arg/getopts/echo.rs | 4 ++-- examples/channels/channels.rs | 2 -- examples/enum/c-like/c-like.rs | 2 -- examples/file/create/create.rs | 4 ++-- examples/file/open/open.rs | 4 ++-- examples/fmt/show.rs | 2 -- examples/fs/fs.rs | 4 ++-- examples/hash/alt-key-types/alt-key-types.rs | 2 -- examples/literals/literals.rs | 2 -- examples/macros/dry/dry.rs | 6 +++--- examples/path/path.rs | 4 ++-- examples/process/pipe/pipe.rs | 2 +- examples/process/process.rs | 2 +- examples/process/wait/wait.rs | 2 +- examples/sockets/client.rs | 6 +++--- examples/sockets/server.rs | 4 ++-- examples/threads/threads.rs | 2 -- examples/timers/timers.rs | 2 +- 18 files changed, 22 insertions(+), 34 deletions(-) diff --git a/examples/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs index fcdef6f78d..2603f60af0 100644 --- a/examples/arg/getopts/echo.rs +++ b/examples/arg/getopts/echo.rs @@ -1,7 +1,7 @@ -#![feature(io)] +#![feature(old_io)] #![feature(rustc_private)] -#![feature(core)] #![feature(env)] +#![feature(core)] #![feature(collections)] extern crate getopts; diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index d82471ba64..db22d4807c 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -1,5 +1,3 @@ -#![feature(std_misc)] - use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; use std::thread; diff --git a/examples/enum/c-like/c-like.rs b/examples/enum/c-like/c-like.rs index 8f7dd66ac2..ec7afa53c2 100644 --- a/examples/enum/c-like/c-like.rs +++ b/examples/enum/c-like/c-like.rs @@ -1,5 +1,3 @@ -#![feature(core)] - // If you'd like to refer to the days without saying // `Day::Monday`, then you use the following notation // use Day::{ diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index b161f8f0e7..2d6eebd612 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,5 +1,5 @@ -#![feature(io)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] use std::old_io::File; diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index 5c03e168ae..6b0bc6872c 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,5 +1,5 @@ -#![feature(io)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] use std::old_io::File; diff --git a/examples/fmt/show.rs b/examples/fmt/show.rs index c2f38059ed..6b06cab457 100644 --- a/examples/fmt/show.rs +++ b/examples/fmt/show.rs @@ -1,5 +1,3 @@ -#![feature(core)] - use std::fmt::{self, Formatter, Display}; // For .abs() use std::num::Float; diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 8a1bccdbf1..925233988a 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -1,5 +1,5 @@ -#![feature(io)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] use std::old_io::fs; use std::old_io::fs::PathExtensions; diff --git a/examples/hash/alt-key-types/alt-key-types.rs b/examples/hash/alt-key-types/alt-key-types.rs index 2e8a6e6e61..19103b4ba1 100644 --- a/examples/hash/alt-key-types/alt-key-types.rs +++ b/examples/hash/alt-key-types/alt-key-types.rs @@ -1,5 +1,3 @@ -#![feature(hash)] - use std::collections::HashMap; // Eq requires that you derive PartialEq on the type. diff --git a/examples/literals/literals.rs b/examples/literals/literals.rs index 20a93bdbd0..f8d70f7dc7 100644 --- a/examples/literals/literals.rs +++ b/examples/literals/literals.rs @@ -1,5 +1,3 @@ -#![feature(core)] - fn main() { // Integer addition println!("1 + 2 = {}", 1u32 + 2); diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index 59ec3f2a37..4cf7fb2a76 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -60,8 +60,8 @@ mod test { } // test add_assign, mul_assign and sub_assign - test!(add_assign, 1us, 2us, 3us); - test!(mul_assign, 2us, 3us, 6us); - test!(sub_assign, 3us, 2us, 1us); + test!(add_assign, 1usize, 2usize, 3usize); + test!(mul_assign, 2usize, 3usize, 6usize); + test!(sub_assign, 3usize, 2usize, 1usize); } diff --git a/examples/path/path.rs b/examples/path/path.rs index 8d88b64877..21d26513ec 100644 --- a/examples/path/path.rs +++ b/examples/path/path.rs @@ -1,5 +1,5 @@ -#![feature(path)] -#![feature(io)] +#![feature(old_path)] +#![feature(old_io)] use std::old_io::fs::PathExtensions; diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index eb1ed81b12..340c25cf79 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,4 +1,4 @@ -#![feature(io)] +#![feature(old_io)] use std::old_io::process::Command; diff --git a/examples/process/process.rs b/examples/process/process.rs index 231163afba..14164ba4e3 100644 --- a/examples/process/process.rs +++ b/examples/process/process.rs @@ -1,4 +1,4 @@ -#![feature(io)] +#![feature(old_io)] use std::old_io::process::{Command,ProcessOutput}; diff --git a/examples/process/wait/wait.rs b/examples/process/wait/wait.rs index ca3769b843..8400a21728 100644 --- a/examples/process/wait/wait.rs +++ b/examples/process/wait/wait.rs @@ -1,4 +1,4 @@ -#![feature(io)] +#![feature(old_io)] use std::old_io::process::Command; diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index f4ccb09504..079039853a 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -1,7 +1,7 @@ -#![feature(io)] -#![feature(core)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] #![feature(env)] +#![feature(core)] use std::env; use common::SOCKET_PATH; diff --git a/examples/sockets/server.rs b/examples/sockets/server.rs index 3249fbf21e..84973916d1 100644 --- a/examples/sockets/server.rs +++ b/examples/sockets/server.rs @@ -1,5 +1,5 @@ -#![feature(io)] -#![feature(path)] +#![feature(old_io)] +#![feature(old_path)] use common::SOCKET_PATH; use std::old_io::fs; diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index ad9ff18d49..b476976b84 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,5 +1,3 @@ -#![feature(std_misc)] - use std::thread; static NTHREADS: i32 = 10; diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index ea806a64b7..738377ddcd 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -1,5 +1,5 @@ #![feature(core)] -#![feature(io)] +#![feature(old_io)] #![feature(std_misc)] use std::old_io::Timer; From edd75a47786869646e4b5f0ff4af64c1819cae81 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 24 Feb 2015 19:02:43 +0100 Subject: [PATCH 0136/1122] clone: Use newer Box syntax and Debug trait for printing --- examples/clone/clone.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index a6b99d19fa..c0c6edd756 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -19,7 +19,7 @@ fn main() { println!("copy: {:?}", copied_nil); // Instantiate a `Pair` - let pair = Pair(box 1, box 2); + let pair = Pair(Box::new(1), Box::new(2)); println!("original: {:?}", pair); // Copy `pair` into `moved_pair`, moves resources @@ -27,7 +27,7 @@ fn main() { println!("copy: {:?}", moved_pair); // Error! `pair` has lost it resources - //println!("original: {}", pair); + println!("original: {:?}", pair); // TODO ^ Try uncommenting this line // "Clone" `moved_pair` into `cloned_pair` (resources included) From 486f5214ec4e8fd68c20f78ce11d6da7b5923da3 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 24 Feb 2015 19:10:45 +0100 Subject: [PATCH 0137/1122] clone: Remove feature gate --- examples/clone/clone.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index c0c6edd756..d8b6c59990 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -1,5 +1,3 @@ -#![feature(box_syntax)] - // A unit struct without resources #[derive(Debug, Copy)] struct Nil; From d6c1f21cd37cc5a53caa9cb258fea9ad3cae29bf Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 13:12:40 -0500 Subject: [PATCH 0138/1122] Remove some feature(core)s --- examples/arg/getopts/echo.rs | 9 ++++----- examples/arg/matching/match_args.rs | 7 +++---- examples/lifetime/explicit/explicit.rs | 3 +-- examples/sockets/client.rs | 10 ++++------ examples/str/str.rs | 3 +-- src/main.rs | 3 +-- 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/examples/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs index 2603f60af0..581261ea6b 100644 --- a/examples/arg/getopts/echo.rs +++ b/examples/arg/getopts/echo.rs @@ -1,13 +1,11 @@ #![feature(old_io)] #![feature(rustc_private)] #![feature(env)] -#![feature(core)] #![feature(collections)] extern crate getopts; use std::env; -use std::old_io::{print, println}; use std::old_io::stdio; static VERSION: &'static str = "1.0.0"; @@ -47,8 +45,9 @@ fn main() { println!(" {} [SHORT-OPTION]... [STRING]...", program); println!(" {} LONG-OPTION", program); println!(""); - println(getopts::usage("Echo the STRING(s) to standard output.", &opts) - .as_slice()); + let usage = getopts::usage("Echo the STRING(s) to standard output.", + &opts); + println!("{}", usage); return; } @@ -60,7 +59,7 @@ fn main() { if !matches.free.is_empty() { //^ `matches.free` contains all the arguments that are not options. let string = matches.free.connect(" "); - print(string.as_slice()); + println!("{}", string); } if !matches.opt_present("n") { diff --git a/examples/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs index bdb9acf1c0..6efcd72389 100644 --- a/examples/arg/matching/match_args.rs +++ b/examples/arg/matching/match_args.rs @@ -1,4 +1,3 @@ -#![feature(core)] #![feature(env)] use std::env; @@ -23,14 +22,14 @@ fn main() { let args: Vec = env::args().map(|x| x.to_string()) .collect(); - match args.as_slice() { + match &args[..] { // no arguments passed [ref name] => { println!("My name is '{}'. Try passing some arguments!", name); }, // one argument passed [_, ref string] => { - if string.as_slice() == "42" { + if string == &"42" { println!("This is the answer!"); } else { println!("This is not the answer."); @@ -50,7 +49,7 @@ fn main() { }, }; // parse the command - match cmd.as_slice() { + match &cmd[..] { "increase" => increase(number), "decrease" => decrease(number), _ => { diff --git a/examples/lifetime/explicit/explicit.rs b/examples/lifetime/explicit/explicit.rs index 2523d257c0..bc0b8ea8de 100644 --- a/examples/lifetime/explicit/explicit.rs +++ b/examples/lifetime/explicit/explicit.rs @@ -1,4 +1,3 @@ -#![feature(core)] #![feature(collections)] struct Book { @@ -9,7 +8,7 @@ struct Book { } fn get_title<'a>(book: &'a Book) -> &'a str { - book.title.as_slice() + &book.title } fn main() { diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs index 079039853a..41bb6f5c50 100644 --- a/examples/sockets/client.rs +++ b/examples/sockets/client.rs @@ -1,7 +1,6 @@ #![feature(old_io)] #![feature(old_path)] #![feature(env)] -#![feature(core)] use std::env; use common::SOCKET_PATH; @@ -16,10 +15,9 @@ fn main() { let socket = Path::new(SOCKET_PATH); // First argument is the message to be sent - let message = match args.as_slice() { - [_, ref message] => message.as_slice(), - _ => panic!("wrong number of arguments"), - }; + if args.len() != 2 { + panic!("wrong number of arguments"); + } // Connect to socket let mut stream = match UnixStream::connect(&socket) { @@ -28,7 +26,7 @@ fn main() { }; // Send message - match stream.write_str(message) { + match stream.write_str(&args[1]) { Err(_) => panic!("couldn't send message"), Ok(_) => {} } diff --git a/examples/str/str.rs b/examples/str/str.rs index 55627b1d95..761fc530f0 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -1,5 +1,4 @@ #![feature(collections)] -#![feature(core)] #![feature(str_words)] fn main() { @@ -31,7 +30,7 @@ fn main() { // The trimmed string is a slice to the original string, hence no new // allocation is performed let chars_to_trim: &[char] = &[' ', ',']; - let trimmed_str: &str = string.as_slice().trim_matches(chars_to_trim); + let trimmed_str: &str = string.trim_matches(chars_to_trim); println!("Used characters: {}", trimmed_str); // Heap allocate a string diff --git a/src/main.rs b/src/main.rs index 4debc39966..976d0d8c53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ #![feature(env)] #![feature(old_io)] #![feature(old_path)] -#![feature(core)] #![deny(warnings)] #![feature(int_uint)] @@ -47,7 +46,7 @@ fn main() { .collect::>() .connect("\n"); - match file::write(&Path::new("stage/SUMMARY.md"), summary.as_slice()) { + match file::write(&Path::new("stage/SUMMARY.md"), &summary) { Err(why) => panic!("{}", why), Ok(_) => {}, } From 1a066d3474e353a71365cbba488bf8c1eb10bac1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 13:38:21 -0500 Subject: [PATCH 0139/1122] Remove box_syntax feature gate Except for what's in https://github.com/rust-lang/rust-by-example/pull/472 --- examples/borrow/ref/ref.rs | 3 +-- examples/box/box.rs | 11 +++++------ examples/enum/enum.rs | 4 +--- examples/methods/methods.rs | 4 +--- examples/move/move.rs | 4 +--- examples/move/mut/mut.rs | 4 +--- examples/panic/panic.rs | 4 +--- examples/raii/raii.rs | 8 +++----- 8 files changed, 14 insertions(+), 28 deletions(-) diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index aabd33bb90..92b3660a50 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,4 +1,3 @@ -#![feature(box_syntax)] #![feature(box_patterns)] #[derive(Copy)] @@ -29,7 +28,7 @@ fn main() { println!("point is ({}, {})", point.x, point.y); println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); - let mut tuple = (box 5u32, 3u32); + let mut tuple = (Box::new(5u32), 3u32); { // `ref` can also be paired with `box` to take a mutable reference to diff --git a/examples/box/box.rs b/examples/box/box.rs index 0e0746c3a5..de981e1192 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,4 +1,3 @@ -#![feature(box_syntax)] #![feature(box_patterns)] use std::mem; @@ -22,7 +21,7 @@ fn origin() -> Point { fn boxed_origin() -> Box { // Allocate this point in the heap, and return a pointer to it - box Point { x: 0.0, y: 0.0 } + Box::new(Point { x: 0.0, y: 0.0 }) } fn main() { @@ -35,16 +34,16 @@ fn main() { }; // Heap allocated rectangle - let boxed_rectangle: Box = box Rectangle { + let boxed_rectangle: Box = Box::new(Rectangle { p1: origin(), p2: origin() - }; + }); // The output of functions can be boxed - let boxed_point: Box = box origin(); + let boxed_point: Box = Box::new(origin()); // Double indirection - let box_in_a_box: Box> = box boxed_origin(); + let box_in_a_box: Box> = Box::new(boxed_origin()); println!("Point occupies {} bytes in the stack", mem::size_of_val(&point)); diff --git a/examples/enum/enum.rs b/examples/enum/enum.rs index d6955d1140..43c161afe4 100644 --- a/examples/enum/enum.rs +++ b/examples/enum/enum.rs @@ -1,5 +1,3 @@ -#![feature(box_syntax)] - // Allow Cons and Nil to be referred to without namespacing use List::{Cons, Nil}; @@ -22,7 +20,7 @@ impl List { // Consume a list, and return the same list with a new element at its front fn prepend(self, elem: u32) -> List { // `Cons` also has type List - Cons(elem, box self) + Cons(elem, Box::new(self)) } // Return the length of the list diff --git a/examples/methods/methods.rs b/examples/methods/methods.rs index 4fa66d9711..f33df1b5ff 100644 --- a/examples/methods/methods.rs +++ b/examples/methods/methods.rs @@ -1,5 +1,3 @@ -#![feature(box_syntax)] - use std::num::Float; // To be able to use .abs(), you must include this @@ -102,7 +100,7 @@ fn main() { // Ok, mutable object can call mutable methods square.translate(1.0, 1.0); - let pair = Pair(box 1, box 2); + let pair = Pair(Box::new(1), Box::new(2)); pair.destroy(); diff --git a/examples/move/move.rs b/examples/move/move.rs index c06bf8972b..3c42928aba 100644 --- a/examples/move/move.rs +++ b/examples/move/move.rs @@ -1,5 +1,3 @@ -#![feature(box_syntax)] - // This function takes ownership of the heap allocated memory fn destroy_box(c: Box) { println!("destroying a box that contains {}", c); @@ -18,7 +16,7 @@ fn main() { println!("x is {}, and y is {}", x, y); // `a` is a pointer to a heap allocated integer - let a = box 5i32; + let a = Box::new(5i32); println!("a contains: {}", a); diff --git a/examples/move/mut/mut.rs b/examples/move/mut/mut.rs index ce8dcf0637..1de28eb697 100644 --- a/examples/move/mut/mut.rs +++ b/examples/move/mut/mut.rs @@ -1,7 +1,5 @@ -#![feature(box_syntax)] - fn main() { - let immutable_box = box 5u32; + let immutable_box = Box::new(5u32); println!("immutable_box contains {}", immutable_box); diff --git a/examples/panic/panic.rs b/examples/panic/panic.rs index f0e065de9c..b386dc82e7 100644 --- a/examples/panic/panic.rs +++ b/examples/panic/panic.rs @@ -1,5 +1,3 @@ -#![feature(box_syntax)] - // Re-implementation of integer division (/) fn division(dividend: i32, divisor: i32) -> i32 { if divisor == 0 { @@ -13,7 +11,7 @@ fn division(dividend: i32, divisor: i32) -> i32 { // The `main` task fn main() { // Heap allocated integer - let _x = box 0i32; + let _x = Box::new(0i32); // This operation will trigger a task failure division(3, 0); diff --git a/examples/raii/raii.rs b/examples/raii/raii.rs index 18a9ed32a5..03a59d4600 100644 --- a/examples/raii/raii.rs +++ b/examples/raii/raii.rs @@ -1,20 +1,18 @@ -#![feature(box_syntax)] - fn create_box() { // Allocate an integer in the heap - let _function_box = box 3i32; + let _function_box = Box::new(3i32); // `_function_box` gets destroyed here, memory gets freed } fn main() { // Allocate an integer in the heap - let _boxed_int = box 5i32; + let _boxed_int = Box::new(5i32); // new (smaller) scope { // Another heap allocated integer - let _short_lived_box = box 4i32; + let _short_lived_box = Box::new(4i32); // `_short_lived_box` gets destroyed here, memory gets freed } From 186b86f15ad3c32ff0f63e167fac41d7d5212a34 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 24 Feb 2015 19:54:42 +0100 Subject: [PATCH 0140/1122] clone: Make failing code a comment again --- examples/clone/clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index d8b6c59990..e5d026abef 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -25,7 +25,7 @@ fn main() { println!("copy: {:?}", moved_pair); // Error! `pair` has lost it resources - println!("original: {:?}", pair); + //println!("original: {:?}", pair); // TODO ^ Try uncommenting this line // "Clone" `moved_pair` into `cloned_pair` (resources included) From 9ce6620103aa724b63df0442dbf4ba8dbf8bd936 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 15:05:55 -0500 Subject: [PATCH 0141/1122] remove box patterns They're behind a flag, and we don't know when they're coming back --- examples/borrow/ref/ref.rs | 12 +----------- examples/box/box.rs | 7 ------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index 92b3660a50..6973d6bd42 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,5 +1,3 @@ -#![feature(box_patterns)] - #[derive(Copy)] struct Point { x: i32, y: i32 } @@ -28,15 +26,7 @@ fn main() { println!("point is ({}, {})", point.x, point.y); println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); - let mut tuple = (Box::new(5u32), 3u32); - - { - // `ref` can also be paired with `box` to take a mutable reference to - // the data contained in the box - let (box ref mut i, _) = tuple; - - *i = 3; - } + let tuple = (Box::new(5u32), 3u32); println!("tuple is {:?}", tuple); } diff --git a/examples/box/box.rs b/examples/box/box.rs index de981e1192..18da715e15 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,5 +1,3 @@ -#![feature(box_patterns)] - use std::mem; #[allow(dead_code)] @@ -62,9 +60,4 @@ fn main() { let unboxed_point: Point = *boxed_point; println!("Unboxed point occupies {} bytes in the stack", mem::size_of_val(&unboxed_point)); - - // Unboxing via a destructuring pattern - let box another_unboxed_point = boxed_point; - println!("Another unboxed point occupies {} bytes in the stack", - mem::size_of_val(&another_unboxed_point)); } From d8574d9b7c871bbc3a6a8567e6eba8632ca2e24f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:15:55 -0500 Subject: [PATCH 0142/1122] remove collections flag --- examples/lifetime/explicit/explicit.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/lifetime/explicit/explicit.rs b/examples/lifetime/explicit/explicit.rs index bc0b8ea8de..04f7529819 100644 --- a/examples/lifetime/explicit/explicit.rs +++ b/examples/lifetime/explicit/explicit.rs @@ -1,5 +1,3 @@ -#![feature(collections)] - struct Book { // `String` is a heap allocated string title: String, @@ -15,8 +13,8 @@ fn main() { let geb = Book { // construct a `String` from a reference to a string (`&'static str`) // by copying of the data - author: String::from_str("Douglas Hofstadter"), - title: String::from_str("Godel, Escher, Bach"), + author: "Douglas Hofstadter".to_string(), + title: "Godel, Escher, Bach".to_string(), year: 1979, }; From abef551c58b10c7bb58c980531c1fb9730ddf0b9 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:19:35 -0500 Subject: [PATCH 0143/1122] remove warnings from main.rs --- src/main.rs | 1 - src/markdown.rs | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 976d0d8c53..3a28ebec65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -#![feature(env)] #![feature(old_io)] #![feature(old_path)] diff --git a/src/markdown.rs b/src/markdown.rs index 231cf39171..7c57647fa1 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -52,14 +52,14 @@ impl<'a, 'b> Markdown<'a, 'b> { let re = Regex::new(r"\{(.*\.rs)\}").unwrap(); let mut table = Vec::new(); - for line in self.content.as_slice().lines() { + for line in self.content.lines() { match re.captures(line) { None => {}, Some(captures) => { let src = captures.at(1).unwrap(); let input = format!("{{{}}}", src); let p = format!("examples/{}/{}/{}", prefix, id, src); - let output = match file::read(&Path::new(p.as_slice())) { + let output = match file::read(&Path::new(&p)) { Err(_) => { return Err(format!("{} not found", p)); }, @@ -75,8 +75,8 @@ impl<'a, 'b> Markdown<'a, 'b> { } for (input, output) in table.into_iter() { - self.content = self.content.replace(input.as_slice(), - output.as_slice()); + self.content = self.content.replace(&input, + &output); } Ok(()) @@ -92,7 +92,7 @@ impl<'a, 'b> Markdown<'a, 'b> { file::mkdir(&dir); let mut table = Vec::new(); - for line in self.content.as_slice().lines() { + for line in self.content.lines() { match r.captures(line) { None => {}, Some(captures) => { @@ -111,8 +111,8 @@ impl<'a, 'b> Markdown<'a, 'b> { } for (input, output) in table.into_iter() { - self.content = self.content.replace(input.as_slice(), - output.as_slice()); + self.content = self.content.replace(&input, + &output); } Ok(()) @@ -125,7 +125,7 @@ impl<'a, 'b> Markdown<'a, 'b> { let mut once_ = false; let mut table = Vec::new(); - for line in self.content.as_slice().lines() { + for line in self.content.lines() { match re.captures(line) { None => {}, Some(captures) => { @@ -139,12 +139,12 @@ impl<'a, 'b> Markdown<'a, 'b> { let input = format!("{{{}.play}}", srcbase); let src = format!("{}.rs", srcbase); let p = format!("examples/{}/{}/{}", prefix, id, src); - let output = match file::read(&Path::new(p.as_slice())) { + let output = match file::read(&Path::new(&p)) { Err(_) => { return Err(format!("{} not found", p)); }, Ok(source) => { - playpen::editor(source.as_slice()) + playpen::editor(&source) } }; @@ -154,8 +154,8 @@ impl<'a, 'b> Markdown<'a, 'b> { } for (input, output) in table.into_iter() { - self.content = self.content.replace(input.as_slice(), - output.as_slice()); + self.content = self.content.replace(&input, + &output); } Ok(()) @@ -164,6 +164,6 @@ impl<'a, 'b> Markdown<'a, 'b> { fn save(&self) -> Result<(), String> { let path = Path::new(format!("stage/{}/{}.md", self.prefix, self.id)); - file::write(&path, self.content.as_slice()) + file::write(&path, &self.content) } } From 35d5e5397cd0095b955479b0c7812f30fda3251e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:21:19 -0500 Subject: [PATCH 0144/1122] remove more warnings --- src/example.rs | 10 +++++----- src/file.rs | 2 +- src/main.rs | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/example.rs b/src/example.rs index c59bbaf77d..3f8e32e226 100644 --- a/src/example.rs +++ b/src/example.rs @@ -16,7 +16,7 @@ impl Example { pub fn get_list() -> Vec { match file::read(&Path::new("examples/structure.json")) { Err(why) => panic!("{}", why), - Ok(string) => match json::Json::from_str(string.as_slice()) { + Ok(string) => match json::Json::from_str(&string) { Err(_) => panic!("structure.json is not valid json"), Ok(json) => { match Decodable::decode(&mut json::Decoder::new(json)) { @@ -41,12 +41,12 @@ impl Example { indent: uint, prefix: String) { - let id = self.id.as_slice(); - let prefix = prefix.as_slice(); - let title = self.title.as_slice(); + let id = &self.id; + let prefix = &prefix; + let title = &self.title; let entry = - match Markdown::process(number.as_slice(), id, title, prefix) { + match Markdown::process(&number, id, title, prefix) { Ok(_) => { let md = if prefix.chars().all(|c| c.is_whitespace()) { format!("{}.md", id) diff --git a/src/file.rs b/src/file.rs index 3f31ab16f2..fced155e32 100644 --- a/src/file.rs +++ b/src/file.rs @@ -46,7 +46,7 @@ pub fn run(prefix: &str, id: &str, src: &str) -> Result { Ok(ProcessOutput { error, output, status }) => { let mut s = String::from_utf8(output).unwrap(); if !status.success() { - s.push_str(String::from_utf8(error).unwrap().as_slice()); + s.push_str(&String::from_utf8(error).unwrap()); } Ok(s) diff --git a/src/main.rs b/src/main.rs index 3a28ebec65..7a3b1773da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![feature(old_io)] #![feature(old_path)] +#![feature(env)] #![deny(warnings)] #![feature(int_uint)] From 279c36ff3ed466306832a5e2895db0823efb6467 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:21:54 -0500 Subject: [PATCH 0145/1122] remove final warnings --- src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.rs b/src/main.rs index 7a3b1773da..b7f09cff0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![feature(old_io)] #![feature(old_path)] #![feature(env)] +#![feature(core)] #![deny(warnings)] #![feature(int_uint)] From fc43614e09b4d9c91e0958849314d85433a52059 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:37:30 -0500 Subject: [PATCH 0146/1122] Fix up README --- examples/README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/README.md b/examples/README.md index 1b656bf45c..b6ca08f54c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,18 +1,19 @@ # Rust by Example -[Rust][rust] is a programming language with a focus on -type safety, memory safety, concurrency and performance. +[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 book is a collection of bitesize examples that illustrate various rustic -concepts and the Rust distribution libraries. The source code is hosted -[here][home]. +Rust by Example is a collection of examples that illustrate various Rust +concepts and the standard libraries. You can also [check out the source code +for this site][home]. -Be sure to have Rust [installed][install] and the [docs][std] at hand, -and let's start! +Be sure to have Rust [installed][install] and the [docs][std] at hand, and +let's start! -*Note*: This book will follow the nightly version of Rust until we reach -version 1.0; it's highly possible that some examples won't work with snapshot -versions like 0.10, so be sure to use a nightly version! +*Note*: Rust by Example follows the nightly builds until the beta or possibly +the 1.0.0 final release. If you're following along on your computer, make sure +to have the latest Rust installed. [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html From 1cbb2e019f52c45c3255ad3581855cd5d9eadeaf Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:46:03 -0500 Subject: [PATCH 0147/1122] Print adjustments --- examples/print/print.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index cd8e88c9d2..585d186a45 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -1,25 +1,23 @@ fn main() { - // `print!` is like `println!` but it doesn't add a newline at the end - print!("January has "); - - // `{}` are placeholders for arguments that will be stringified + // `{}` are placeholders for arguments that will be stringified. println!("{} days", 31); + // Without a suffix, 31 becomes an i32. You can change what type 31 is, // with a suffix, and that is covered in the next chapter. - // The positional arguments can be reused along the template + // The positional arguments can be reused along the template. println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); - // Named arguments can also be used + // Named arguments can also be used. println!("{subject} {verb} {predicate}", predicate="over the lazy dog", subject="the quick brown fox", verb="jumps"); - // Special formatting can be specified in the placeholder after a `:` + // Special formatting can be specified in the placeholder after a `:`. println!("{} of {:b} people know binary, the other half don't", 1, 2); - // Error! You are missing an argument + // Error! You are missing an argument. println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" } From 0fe2fbcea263540f2721e1fe2f6e2f69e8163469 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:50:15 -0500 Subject: [PATCH 0148/1122] Variables -> variable bindings --- Makefile | 6 +++--- examples/structure.json | 2 +- .../{variables => variable_bindings}/declare/declare.rs | 0 examples/{variables => variable_bindings}/declare/input.md | 0 examples/{variables => variable_bindings}/input.md | 2 +- examples/{variables => variable_bindings}/mut/input.md | 0 examples/{variables => variable_bindings}/mut/mut.rs | 0 examples/{variables => variable_bindings}/scope/input.md | 0 examples/{variables => variable_bindings}/scope/scope.rs | 0 .../variables.rs => variable_bindings/variable_bindings.rs} | 0 10 files changed, 5 insertions(+), 5 deletions(-) rename examples/{variables => variable_bindings}/declare/declare.rs (100%) rename examples/{variables => variable_bindings}/declare/input.md (100%) rename examples/{variables => variable_bindings}/input.md (75%) rename examples/{variables => variable_bindings}/mut/input.md (100%) rename examples/{variables => variable_bindings}/mut/mut.rs (100%) rename examples/{variables => variable_bindings}/scope/input.md (100%) rename examples/{variables => variable_bindings}/scope/scope.rs (100%) rename examples/{variables/variables.rs => variable_bindings/variable_bindings.rs} (100%) diff --git a/Makefile b/Makefile index 2ea5c54ed1..d62ead4e87 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/print/print.rs \ examples/type/cast/cast.rs \ examples/type/type.rs \ - examples/variables/scope/scope.rs \ - examples/variables/mut/mut.rs \ - examples/variables/declare/declare.rs \ + examples/variable_bindings/scope/scope.rs \ + examples/variable_bindings/mut/mut.rs \ + examples/variable_bindings/declare/declare.rs \ examples/vec/vec.rs srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) diff --git a/examples/structure.json b/examples/structure.json index 9c35f8b67e..edbd4b3bc9 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -2,7 +2,7 @@ { "id": "hello", "title": "Hello World", "children": null }, { "id": "print", "title": "Formatted print", "children": null }, { "id": "literals", "title": "Literals and operators", "children": null }, - { "id": "variables", "title": "Variables", "children": [ + { "id": "variable_bindings", "title": "Variable Bindings", "children": [ { "id": "mut", "title": "Mutability", "children": null }, { "id": "scope", "title": "Scope and shadowing", "children": null }, { "id": "declare", "title": "Declare first", "children": null } diff --git a/examples/variables/declare/declare.rs b/examples/variable_bindings/declare/declare.rs similarity index 100% rename from examples/variables/declare/declare.rs rename to examples/variable_bindings/declare/declare.rs diff --git a/examples/variables/declare/input.md b/examples/variable_bindings/declare/input.md similarity index 100% rename from examples/variables/declare/input.md rename to examples/variable_bindings/declare/input.md diff --git a/examples/variables/input.md b/examples/variable_bindings/input.md similarity index 75% rename from examples/variables/input.md rename to examples/variable_bindings/input.md index 22358bb6cf..f191c25c40 100644 --- a/examples/variables/input.md +++ b/examples/variable_bindings/input.md @@ -1,3 +1,3 @@ Values (like literals) can be bound to variables, using the `let` binding. -{variables.play} +{variable_bindings.play} diff --git a/examples/variables/mut/input.md b/examples/variable_bindings/mut/input.md similarity index 100% rename from examples/variables/mut/input.md rename to examples/variable_bindings/mut/input.md diff --git a/examples/variables/mut/mut.rs b/examples/variable_bindings/mut/mut.rs similarity index 100% rename from examples/variables/mut/mut.rs rename to examples/variable_bindings/mut/mut.rs diff --git a/examples/variables/scope/input.md b/examples/variable_bindings/scope/input.md similarity index 100% rename from examples/variables/scope/input.md rename to examples/variable_bindings/scope/input.md diff --git a/examples/variables/scope/scope.rs b/examples/variable_bindings/scope/scope.rs similarity index 100% rename from examples/variables/scope/scope.rs rename to examples/variable_bindings/scope/scope.rs diff --git a/examples/variables/variables.rs b/examples/variable_bindings/variable_bindings.rs similarity index 100% rename from examples/variables/variables.rs rename to examples/variable_bindings/variable_bindings.rs From 95bc3ae7fe7e07f3916f6fb693f77bc5184d3639 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 17:55:55 -0500 Subject: [PATCH 0149/1122] variable bindings --- examples/variable_bindings/declare/declare.rs | 20 ++++++++--------- examples/variable_bindings/declare/input.md | 5 +++-- examples/variable_bindings/mut/input.md | 4 ++-- examples/variable_bindings/mut/mut.rs | 12 +++++----- examples/variable_bindings/scope/input.md | 6 ++--- examples/variable_bindings/scope/scope.rs | 22 +++++++++---------- .../variable_bindings/variable_bindings.rs | 5 +++-- 7 files changed, 38 insertions(+), 36 deletions(-) diff --git a/examples/variable_bindings/declare/declare.rs b/examples/variable_bindings/declare/declare.rs index e2e0c06537..a678cfbb65 100644 --- a/examples/variable_bindings/declare/declare.rs +++ b/examples/variable_bindings/declare/declare.rs @@ -1,23 +1,23 @@ fn main() { - // Declare a variable - let a_variable; + // Declare a variable binding + let a_binding; { let x = 2; - // Initialize the variable - a_variable = x * x; + // Initialize the binding + a_binding = x * x; } - println!("a variable: {}", a_variable); + println!("a binding: {}", a_binding); - let another_variable; + let another_binding; - // Error! Use of uninitialized variable - println!("another variable: {}", another_variable); + // Error! Use of uninitialized binding + println!("another binding: {}", another_binding); // FIXME ^ Comment out this line - another_variable = 1; + another_binding = 1; - println!("another variable: {}", another_variable); + println!("another binding: {}", another_binding); } diff --git a/examples/variable_bindings/declare/input.md b/examples/variable_bindings/declare/input.md index 01b6cd8ac5..63339745ae 100644 --- a/examples/variable_bindings/declare/input.md +++ b/examples/variable_bindings/declare/input.md @@ -1,5 +1,6 @@ -It's possible to declare variables first, and initialize them later. However, -this form is seldom used, as it may lead to the use of uninitialized variables. +It's possible to declare variable bindings first, and initialize them later. +However, this form is seldom used, as it may lead to the use of uninitialized +variables. {declare.play} diff --git a/examples/variable_bindings/mut/input.md b/examples/variable_bindings/mut/input.md index 309d762dd3..ca010fee4d 100644 --- a/examples/variable_bindings/mut/input.md +++ b/examples/variable_bindings/mut/input.md @@ -1,5 +1,5 @@ -Variables are immutable by default, but this can be overridden using the `mut` -modifier. +Variable bindings are immutable by default, but this can be overridden using +the `mut` modifier. {mut.play} diff --git a/examples/variable_bindings/mut/mut.rs b/examples/variable_bindings/mut/mut.rs index d2a8470a74..72695e12ff 100644 --- a/examples/variable_bindings/mut/mut.rs +++ b/examples/variable_bindings/mut/mut.rs @@ -1,15 +1,15 @@ fn main() { - let _immutable_variable = 1; - let mut mutable_variable = 1; + let _immutable_binding = 1; + let mut mutable_binding = 1; - println!("Before mutation: {}", mutable_variable); + println!("Before mutation: {}", mutable_binding); // Ok - mutable_variable += 1; + mutable_binding += 1; - println!("After mutation: {}", mutable_variable); + println!("After mutation: {}", mutable_binding); // Error! - _immutable_variable += 1; + _immutable_binding += 1; // FIXME ^ Comment out this line } diff --git a/examples/variable_bindings/scope/input.md b/examples/variable_bindings/scope/input.md index fe781b9af0..ff558df92a 100644 --- a/examples/variable_bindings/scope/input.md +++ b/examples/variable_bindings/scope/input.md @@ -1,6 +1,6 @@ -Variables have local scope, and are constrained to live in a *block* (a block -is a collection of statements enclosed by braces `{}`). Also, -[variable shadowing][variable-shadow] is allowed. +Variable bindings have a scope, and are constrained to live in a *block*. A +block is a collection of statements enclosed by braces `{}`. Also, [variable +shadowing][variable-shadow] is allowed. {scope.play} diff --git a/examples/variable_bindings/scope/scope.rs b/examples/variable_bindings/scope/scope.rs index 409be705dc..8fe06b9ff4 100644 --- a/examples/variable_bindings/scope/scope.rs +++ b/examples/variable_bindings/scope/scope.rs @@ -1,24 +1,24 @@ fn main() { - // This variable lives in the main function - let long_lived_variable = 1; + // This binding lives in the main function + let long_lived_binding = 1; // This is a block, and has a smaller scope than the main function { - // This variable only exists in this block - let short_lived_variable = 2; + // This binding only exists in this block + let short_lived_binding = 2; - println!("inner short: {}", short_lived_variable); + println!("inner short: {}", short_lived_binding); - // This variable *shadows* the outer one - let long_lived_variable = 5_f32; + // This binding *shadows* the outer one + let long_lived_banding = 5_f32; - println!("inner long: {}", long_lived_variable); + println!("inner long: {}", long_lived_binding); } // End of the block - // Error! `short_lived_variable` doesn't exist in this scope - println!("outer short: {}", short_lived_variable); + // Error! `short_lived_binding` doesn't exist in this scope + println!("outer short: {}", short_lived_binding); // FIXME ^ Comment out this line - println!("outer long: {}", long_lived_variable); + println!("outer long: {}", long_lived_binding); } diff --git a/examples/variable_bindings/variable_bindings.rs b/examples/variable_bindings/variable_bindings.rs index f5c486c318..25bd9a2658 100644 --- a/examples/variable_bindings/variable_bindings.rs +++ b/examples/variable_bindings/variable_bindings.rs @@ -10,9 +10,10 @@ fn main() { println!("A boolean: {:?}", a_boolean); println!("Meet the unit value: {:?}", unit); - // The compiler warns about unused variables; these warnings can be - // silenced by prefixing the variable name with an underscore + // The compiler warns about unused variable bindings; these warnings can + // be silenced by prefixing the variable name with an underscore let _unused_variable = 3u32; + let noisy_unused_variable = 2u32; // FIXME ^ Prefix with an underscore to suppress the warning } From cfcc2984c3d0046a37854b21d6e3f393a00999fd Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 18:04:55 -0500 Subject: [PATCH 0150/1122] Edit 'type' --- examples/type/alias/alias.rs | 6 +++--- examples/type/cast/input.md | 2 +- examples/type/inference/inference.rs | 8 ++++---- examples/type/input.md | 2 +- examples/type/literals/input.md | 9 +++++---- examples/type/literals/literals.rs | 5 ----- examples/type/type.rs | 2 +- 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/examples/type/alias/alias.rs b/examples/type/alias/alias.rs index 765a5ec95f..74e6f52938 100644 --- a/examples/type/alias/alias.rs +++ b/examples/type/alias/alias.rs @@ -1,14 +1,14 @@ -// `NanoSecond` is a new name for `u64` +// `NanoSecond` is a new name for `u64`. type NanoSecond = u64; type Inch = u64; -// Use an attribute to silence warning +// Use an attribute to silence warning. #[allow(non_camel_case_types)] type u64_t = u64; // TODO ^ Try removing the attribute fn main() { - // `NanoSecond` = `Inch` = `u64_t` = `u64` + // `NanoSecond` = `Inch` = `u64_t` = `u64`. let nanoseconds: NanoSecond = 5 as u64_t; let inches: Inch = 2 as u64_t; diff --git a/examples/type/cast/input.md b/examples/type/cast/input.md index 7a792d4ee5..98e73bd3ae 100644 --- a/examples/type/cast/input.md +++ b/examples/type/cast/input.md @@ -1,4 +1,4 @@ Rust provides no implicit type conversion (coercion) between primitive types. -But, explicit type conversion (casting) can be achieved using the `as` keyword. +But, explicit type conversion (casting) can be performed using the `as` keyword. {cast.play} diff --git a/examples/type/inference/inference.rs b/examples/type/inference/inference.rs index 6f5db13405..8dde5abe56 100644 --- a/examples/type/inference/inference.rs +++ b/examples/type/inference/inference.rs @@ -1,13 +1,13 @@ fn main() { - // Using local inference, the compiler knows that `elem` has type u8 + // Because of the annotation, the compiler knows that `elem` has type u8. let elem = 5u8; - // Create an empty vector (a growable array) + // Create an empty vector (a growable array). let mut vec = Vec::new(); // At this point the compiler doesn't know the exact type of `vec`, it - // just knows that it's a vector of something (`Vec<_>`) + // just knows that it's a vector of something (`Vec<_>`). - // Insert `elem` in the vector + // Insert `elem` in the vector. vec.push(elem); // Aha! Now the compiler knows that `vec` is a vector of `u8`s (`Vec`) // TODO ^ Try commenting out the `vec.push(elem)` line diff --git a/examples/type/input.md b/examples/type/input.md index dc62a4f284..149cdcb927 100644 --- a/examples/type/input.md +++ b/examples/type/input.md @@ -1,4 +1,4 @@ -Rust provides type safety via its static type-checker. Variables can be type +Rust provides type safety via static typing. Variable bindingss can be type annotated when declared. However, in most cases, the compiler will be able to infer the type of the variable from the context, heavily reducing the annotation burden. diff --git a/examples/type/literals/input.md b/examples/type/literals/input.md index 7d725cacfe..5b02c05840 100644 --- a/examples/type/literals/input.md +++ b/examples/type/literals/input.md @@ -1,9 +1,10 @@ Numeric literals can be type annotated by adding the type as a suffix, with the -exception of `usize` that uses the `us` suffix and `isize` that uses the `is` -suffix. +exception of `usize` that uses the `usize` suffix and `isize` that uses the +`isize` suffix. -The type of unsuffixed literals will depend on how they are used. If no -constraint exists, the compiler will raise an error. +The type of unsuffixed numeric literals will depend on how they are used. If no +constraint exists, the compiler will use `i32` for integers, and `f64` for +floating-point numbers. {literals.play} diff --git a/examples/type/literals/literals.rs b/examples/type/literals/literals.rs index b690b749ef..c0fe85f2be 100644 --- a/examples/type/literals/literals.rs +++ b/examples/type/literals/literals.rs @@ -14,9 +14,4 @@ fn main() { println!("size of `z` in bytes: {}", std::mem::size_of_val(&z)); println!("size of `i` in bytes: {}", std::mem::size_of_val(&i)); println!("size of `f` in bytes: {}", std::mem::size_of_val(&f)); - - // Constraints (summands must have the same type) for `i` and `f` - let _constraint_i = x + i; - let _constraint_f = z + f; - // TODO ^ Try commenting out these two lines } diff --git a/examples/type/type.rs b/examples/type/type.rs index 4073141828..8eea3e6de5 100644 --- a/examples/type/type.rs +++ b/examples/type/type.rs @@ -2,7 +2,7 @@ fn main() { // Type annotated variable let a_float: f64 = 1.0; - // This variable is an `int` + // This variable is an `i32` let mut an_integer = 5i32; // Error! The type of a variable can't be changed From 621165147e9074fe82f3cd33706fae43423f3ab3 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 18:18:48 -0500 Subject: [PATCH 0151/1122] expressions --- examples/expression/input.md | 40 +++++++++++++++++++------- examples/expression/more_statements.rs | 8 ++++++ examples/expression/statements.rs | 6 ++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 examples/expression/more_statements.rs create mode 100644 examples/expression/statements.rs diff --git a/examples/expression/input.md b/examples/expression/input.md index 5e4b0d8179..174cba2ffd 100644 --- a/examples/expression/input.md +++ b/examples/expression/input.md @@ -1,13 +1,33 @@ -In Rust, almost every statement is an expression, meaning that the statement -returns a value. This may not always be desired, so the output can be -suppressed by ending the expression with a semicolon `;`. - -Blocks are expressions too, so they can be used as -[r-values][rvalue] -in assignments. The last expression in the block will be assigned to the -[l-value][lvalue]. -However, if the last expression of the block ends with a semicolon, the -return value will be `()`. +A Rust program is (mostly) made up of a series of statements: + + +``` +fn main() { + // statement + // statement + // statement +} +``` + +There are a few kinds of statements in Rust. The most common two are declaring +a variable binding, and using a `;` with an expression: + +``` +fn main() { + // variable binding + let x = 5; + + // expression; + x; + x + 1; + 15; +} +``` + +Blocks are expressions too, so they can be used as [r-values][rvalue] in +assignments. The last expression in the block will be assigned to the +[l-value][lvalue]. However, if the last expression of the block ends with a +semicolon, the return value will be `()`. {expression.play} diff --git a/examples/expression/more_statements.rs b/examples/expression/more_statements.rs new file mode 100644 index 0000000000..858518bb11 --- /dev/null +++ b/examples/expression/more_statements.rs @@ -0,0 +1,8 @@ +fn main() { + // variable binding: + let x = 5; + + // expression; + x + 1; + 15; +} diff --git a/examples/expression/statements.rs b/examples/expression/statements.rs new file mode 100644 index 0000000000..73c44998b6 --- /dev/null +++ b/examples/expression/statements.rs @@ -0,0 +1,6 @@ +fn main() { + // statement + // statement + // statement + // statement +} From f7fefc772a352a3a64648f3c37f2387a33081efd Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 18:57:23 -0500 Subject: [PATCH 0152/1122] Remove accidentally-committed files Thanks @mdinger --- examples/expression/more_statements.rs | 8 -------- examples/expression/statements.rs | 6 ------ 2 files changed, 14 deletions(-) delete mode 100644 examples/expression/more_statements.rs delete mode 100644 examples/expression/statements.rs diff --git a/examples/expression/more_statements.rs b/examples/expression/more_statements.rs deleted file mode 100644 index 858518bb11..0000000000 --- a/examples/expression/more_statements.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - // variable binding: - let x = 5; - - // expression; - x + 1; - 15; -} diff --git a/examples/expression/statements.rs b/examples/expression/statements.rs deleted file mode 100644 index 73c44998b6..0000000000 --- a/examples/expression/statements.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - // statement - // statement - // statement - // statement -} From d5f8212c34507068284457e21eb3f3819fb99216 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 19:08:23 -0500 Subject: [PATCH 0153/1122] Flow control --- examples/flow_control/for/for.rs | 2 +- examples/flow_control/if-else/if-else.rs | 10 +++++----- examples/flow_control/if-else/input.md | 8 ++++---- examples/flow_control/input.md | 5 ++--- examples/flow_control/while/while.rs | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/examples/flow_control/for/for.rs b/examples/flow_control/for/for.rs index 918f846472..3a91b0c9a9 100644 --- a/examples/flow_control/for/for.rs +++ b/examples/flow_control/for/for.rs @@ -1,6 +1,6 @@ fn main() { // `n` will take the values: 1, 2, ..., 100 in each iteration - for n in 1u32..101 { + for n in 1..101 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { diff --git a/examples/flow_control/if-else/if-else.rs b/examples/flow_control/if-else/if-else.rs index 1b020fe9de..516d4a9745 100644 --- a/examples/flow_control/if-else/if-else.rs +++ b/examples/flow_control/if-else/if-else.rs @@ -1,5 +1,5 @@ fn main() { - let n = 5i32; + let n = 5; if n < 0 { print!("{} is negative", n); @@ -13,16 +13,16 @@ fn main() { if n < 10 && n > -10 { println!(", and is a small number, increase ten-fold"); - // This expression returns an `int` + // This expression returns an `i32`. 10 * n } else { println!(", and is a big number, reduce by two"); - // This expression must return an `int` as well + // This expression must return an `i32` as well. n / 2 - // TODO ^ Try suppressing this expression with a semicolon + // TODO ^ Try suppressing this expression with a semicolon. }; - // ^ Don't forget to put a semicolon here! All the `let` bindings need it + // ^ Don't forget to put a semicolon here! All `let` bindings need it. println!("{} -> {}", n, big_n); } diff --git a/examples/flow_control/if-else/input.md b/examples/flow_control/if-else/input.md index d6cd71b335..f822bd9e8e 100644 --- a/examples/flow_control/if-else/input.md +++ b/examples/flow_control/if-else/input.md @@ -1,6 +1,6 @@ -Branching with if-else is similar to C. Unlike C, the boolean condition doesn't -need to be surrounded by parentheses, and each condition is followed by a -block. If-else conditionals are expressions too, and, because of Rust's type -safety, all branches must return the same type. +Branching with `if`-`else` is similar to other languages. Unlike many of them, +the boolean condition doesn't need to be surrounded by parentheses, and each +condition is followed by a block. `if`-`else` conditionals are expressions, +and, all branches must return the same type. {if-else.play} diff --git a/examples/flow_control/input.md b/examples/flow_control/input.md index d846bfd76c..99e0a348e3 100644 --- a/examples/flow_control/input.md +++ b/examples/flow_control/input.md @@ -1,3 +1,2 @@ -Here we will analyze various flow control structures such as -`if`/`else`, `for` and the related `i..j` notation, `while`, -`loop`, `match` and the related `if let` and `while let` simplifications. +An essential part of any programming languages are ways to modify control flow: +`if`/`else`, `for`, and others. Let's talk about them in Rust. diff --git a/examples/flow_control/while/while.rs b/examples/flow_control/while/while.rs index df9c98e30e..3b37e550ad 100644 --- a/examples/flow_control/while/while.rs +++ b/examples/flow_control/while/while.rs @@ -1,6 +1,6 @@ fn main() { // A counter variable - let mut n = 1u32; + let mut n = 1; // Loop while `n` is less than 101 while n < 101 { From c3efd12815a2d9979e0b7ce269bc815f647dde7e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 19:11:14 -0500 Subject: [PATCH 0154/1122] Match --- examples/flow_control/match/match.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/flow_control/match/match.rs b/examples/flow_control/match/match.rs index ce88c13ec3..cf0c463e0e 100644 --- a/examples/flow_control/match/match.rs +++ b/examples/flow_control/match/match.rs @@ -1,5 +1,5 @@ fn main() { - let number: i32 = 13; + let number = 13; // TODO ^ Try different values for `number` println!("Tell me about {}", number); @@ -16,7 +16,7 @@ fn main() { let boolean = true; // Match is an expression too - let binary: i32 = match boolean { + let binary = match boolean { // The arms of a match must cover all the possible values false => 0, true => 1, From 2a8e78a033273df7142405308249f280b8b02d9b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 24 Feb 2015 19:17:25 -0500 Subject: [PATCH 0155/1122] update fn --- examples/fn/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/input.md b/examples/fn/input.md index c8b9db6c69..05829a6722 100644 --- a/examples/fn/input.md +++ b/examples/fn/input.md @@ -4,7 +4,7 @@ return type must be specified after an arrow `->`. The final expression in the function will be used as return value. Alternatively, the `return` statement can be used to return a value earlier -from within the function, even from inside loops or ifs. +from within the function, even from inside loops or `if`s. Let's rewrite FizzBuzz using functions! From 47351a15eacd07ac6a55a77822d20ef3587cbe7c Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 25 Feb 2015 00:28:59 -0500 Subject: [PATCH 0156/1122] {} to {:?} --- examples/print/print.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/print/print.rs b/examples/print/print.rs index 585d186a45..1d03e65d9e 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -1,23 +1,23 @@ fn main() { - // `{}` are placeholders for arguments that will be stringified. - println!("{} days", 31); + // `{:?}` are placeholders for arguments that will be stringified. + println!("{:?} days", 31); // Without a suffix, 31 becomes an i32. You can change what type 31 is, // with a suffix, and that is covered in the next chapter. // The positional arguments can be reused along the template. - println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); + println!("{0:?}, this is {1:?}. {1:?}, this is {0:?}", "Alice", "Bob"); // Named arguments can also be used. - println!("{subject} {verb} {predicate}", + println!("{subject:?} {verb:?} {predicate:?}", predicate="over the lazy dog", subject="the quick brown fox", verb="jumps"); - // Special formatting can be specified in the placeholder after a `:`. - println!("{} of {:b} people know binary, the other half don't", 1, 2); + // Special formatting can be specified in the place of the `?`. + println!("{:?} of {:b} people know binary, the other half don't", 1, 2); // Error! You are missing an argument. - println!("My name is {0}, {1} {0}", "Bond"); + println!("My name is {0:?}, {1:?} {0:?}", "Bond"); // FIXME ^ Add the missing argument: "James" } From 0bd06bf21a525b322b23eb05fb93e44164c0ed70 Mon Sep 17 00:00:00 2001 From: Nickolay Ponomarev Date: Wed, 25 Feb 2015 09:36:34 +0300 Subject: [PATCH 0157/1122] Link to the related "the ref pattern" When looking up syntax of the ref pattern in destructuring let, I searched for 'destructuring' in the TOC and landed on this page. --- .../match/destructuring/destructure_structures/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flow_control/match/destructuring/destructure_structures/input.md b/examples/flow_control/match/destructuring/destructure_structures/input.md index 634e7883ab..8025cb675d 100644 --- a/examples/flow_control/match/destructuring/destructure_structures/input.md +++ b/examples/flow_control/match/destructuring/destructure_structures/input.md @@ -3,4 +3,4 @@ Similarly, a `struct` can be destructured as shown: {struct.play} ### See also: -[Structs](/structs.html) +[Structs](/structs.html), [The ref pattern](/borrow/ref.html) From 6d1673415a33af772304ceaab0f8ae51d457399b Mon Sep 17 00:00:00 2001 From: clashman Date: Wed, 25 Feb 2015 10:13:25 +0100 Subject: [PATCH 0158/1122] fix typo so that long_lived_binding is actually shadowed --- examples/variable_bindings/scope/scope.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/variable_bindings/scope/scope.rs b/examples/variable_bindings/scope/scope.rs index 8fe06b9ff4..567d2eca2e 100644 --- a/examples/variable_bindings/scope/scope.rs +++ b/examples/variable_bindings/scope/scope.rs @@ -10,7 +10,7 @@ fn main() { println!("inner short: {}", short_lived_binding); // This binding *shadows* the outer one - let long_lived_banding = 5_f32; + let long_lived_binding = 5_f32; println!("inner long: {}", long_lived_binding); } From 05fa009ba6bd4bc01357dca0773b2d4dd02c7c7b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 09:29:17 -0500 Subject: [PATCH 0159/1122] Pin nightly http://users.rust-lang.org/t/psa-the-2015-02-25-nightly-contains-a-broken-cargo/455 This should be reverted in a day or two. (Thanks @barsol) --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 840fd4a9c9..6682578bcf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ language: node_js sudo: true install: - - curl -L -s https://static.rust-lang.org/rustup.sh | sudo sh > /dev/null + - curl -L -s https://static.rust-lang.org/rustup.sh -O + - sudo sh -c 'sh rustup.sh --date=2015-02-22' > /dev/null script: - rustc --version From 563446dfb59edb639822f5b7eacc2809a8d2e636 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:13:27 -0500 Subject: [PATCH 0160/1122] Mod --- examples/mod/input.md | 8 ++++---- examples/structure.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/mod/input.md b/examples/mod/input.md index bba4a49771..8213860450 100644 --- a/examples/mod/input.md +++ b/examples/mod/input.md @@ -1,8 +1,8 @@ Rust provides a powerful module system that can be used to hierarchically split -code in logical units (modules), and manage visibility (public/private) -between them. +code in logical units (modules), and manage visibility (public/private) between +them. -A module is a collection of items like: functions, structs, traits, impl -blocks, and even other modules. +A module is a collection of items: functions, structs, traits, `impl blocks, +and even other modules. {mod.play} diff --git a/examples/structure.json b/examples/structure.json index edbd4b3bc9..e8a8e3684e 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -39,7 +39,7 @@ ] }, { "id": "mod", "title": "Modules", "children": [ { "id": "visibility", "title": "Visibility", "children": null }, - { "id": "use", "title": "The `use` import", "children": null }, + { "id": "use", "title": "The `use` declaration", "children": null }, { "id": "super", "title": "`super` and `self`", "children": null }, { "id": "split", "title": "File hierarchy", "children": null } ] }, From 9e8af0cf3da7f2480f30daf936760909b2a1a880 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:23:13 -0500 Subject: [PATCH 0161/1122] liberty -> library --- examples/crates/lib/erty.rs | 13 ------------- examples/crates/lib/input.md | 10 +++++----- examples/crates/lib/rary.rs | 13 +++++++++++++ examples/crates/link/executable.rs | 10 +++++----- examples/crates/link/input.md | 12 ++++++------ 5 files changed, 29 insertions(+), 29 deletions(-) delete mode 100644 examples/crates/lib/erty.rs create mode 100644 examples/crates/lib/rary.rs diff --git a/examples/crates/lib/erty.rs b/examples/crates/lib/erty.rs deleted file mode 100644 index 6104f64ea3..0000000000 --- a/examples/crates/lib/erty.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub fn public_function() { - println!("called erty's `public_function()`"); -} - -fn private_function() { - println!("called erty's `private_function()`"); -} - -pub fn indirect_access() { - print!("called erty's `indirect_access()`, that\n> "); - - private_function(); -} diff --git a/examples/crates/lib/input.md b/examples/crates/lib/input.md index 33b7114df5..228c566e61 100644 --- a/examples/crates/lib/input.md +++ b/examples/crates/lib/input.md @@ -1,15 +1,15 @@ Let's create a library, and then see how to link it to another crate. -{erty.rs} +{rary.rs} ``` -$ rustc --crate-type=lib erty.rs +$ rustc --crate-type=lib rary.rs $ ls lib* -liberty.rlib +library.rlib ``` Libraries get prefixed with "lib", and by default they get named after their -crate file, but this default name can be overridden using the -[`crate_name` attribute][crate-name]. +crate file, but this default name can be overridden using the [`crate_name` +attribute][crate-name]. [crate-name]: /attribute/crate.html diff --git a/examples/crates/lib/rary.rs b/examples/crates/lib/rary.rs new file mode 100644 index 0000000000..d9425982a1 --- /dev/null +++ b/examples/crates/lib/rary.rs @@ -0,0 +1,13 @@ +pub fn public_function() { + println!("called rary's `public_function()`"); +} + +fn private_function() { + println!("called rary's `private_function()`"); +} + +pub fn indirect_access() { + print!("called rary's `indirect_access()`, that\n> "); + + private_function(); +} diff --git a/examples/crates/link/executable.rs b/examples/crates/link/executable.rs index 42c83c39f5..6942105ee4 100644 --- a/examples/crates/link/executable.rs +++ b/examples/crates/link/executable.rs @@ -1,11 +1,11 @@ -// Link to `liberty`, import items under the `erty` module -extern crate erty; +// Link to `library`, import items under the `rary` module +extern crate rary; fn main() { - erty::public_function(); + rary::public_function(); // Error! `private_function` is private - //erty::private_function(); + //rary::private_function(); - erty::indirect_access(); + rary::indirect_access(); } diff --git a/examples/crates/link/input.md b/examples/crates/link/input.md index 043852b79e..7c433811c1 100644 --- a/examples/crates/link/input.md +++ b/examples/crates/link/input.md @@ -1,14 +1,14 @@ To link a crate to this new library, the `extern crate` declaration must be -used. This will not only link the library, but also import all its items -under a module named the same as the library. The visibility rules that apply -to modules also apply to libraries. +used. This will not only link the library, but also import all its items under +a module named the same as the library. The visibility rules that apply to +modules also apply to libraries. {executable.rs} ``` # The `-L .` argument adds the current directory to the library search path $ rustc -L . executable.rs && ./executable -called erty's `public_function()` -called erty's `indirect_access()`, that -> called erty's `private_function()` +called rary's `public_function()` +called rary's `indirect_access()`, that +> called rary's `private_function()` ``` From 1aab7215ae1d70a63979ce0c91cfb37976a01dcf Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:27:49 -0500 Subject: [PATCH 0162/1122] Attributes: liberty -> library --- examples/attribute/crate/input.md | 2 +- examples/attribute/crate/lib.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/attribute/crate/input.md b/examples/attribute/crate/input.md index 78fd3720f7..8bf8e4b286 100644 --- a/examples/attribute/crate/input.md +++ b/examples/attribute/crate/input.md @@ -10,5 +10,5 @@ When the `crate_type` attribute is used, we no longer need to pass the ``` $ rustc lib.rs $ ls lib* -liberty.rlib +library.rlib ``` diff --git a/examples/attribute/crate/lib.rs b/examples/attribute/crate/lib.rs index 3fc52b6a34..39afc16f51 100644 --- a/examples/attribute/crate/lib.rs +++ b/examples/attribute/crate/lib.rs @@ -1,18 +1,18 @@ // This crate is a library #![crate_type = "lib"] -// The library is named "erty" -#![crate_name = "erty"] +// The library is named "rary" +#![crate_name = "rary"] pub fn public_function() { - println!("called erty's `public_function()`"); + println!("called rary's `public_function()`"); } fn private_function() { - println!("called erty's `private_function()`"); + println!("called rary's `private_function()`"); } pub fn indirect_access() { - print!("called erty's `indirect_access()`, that\n> "); + print!("called rary's `indirect_access()`, that\n> "); private_function(); } From c731a08277d6715d678402022f15d71a57450510 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:42:42 -0500 Subject: [PATCH 0163/1122] thanks @mdinger --- examples/mod/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mod/input.md b/examples/mod/input.md index 8213860450..ea270a2bf5 100644 --- a/examples/mod/input.md +++ b/examples/mod/input.md @@ -2,7 +2,7 @@ Rust provides a powerful module system that can be used to hierarchically split code in logical units (modules), and manage visibility (public/private) between them. -A module is a collection of items: functions, structs, traits, `impl blocks, +A module is a collection of items: functions, structs, traits, `impl` blocks, and even other modules. {mod.play} From 06bb208f8edb086b1acd392d047b67d5a4ab1d0b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:44:14 -0500 Subject: [PATCH 0164/1122] box --- examples/box/input.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/box/input.md b/examples/box/input.md index 5d6cafd3e0..9eed38aad0 100644 --- a/examples/box/input.md +++ b/examples/box/input.md @@ -1,11 +1,9 @@ All values in Rust are stack allocated by default. Values can be *boxed* -(allocated in the heap) using the `box` construct. A box, with type signature -`Box`, is a smart pointer to a heap allocated value of type `T`. When a box -goes out of scope, its destructor is called, the inner object is destroyed, and -the memory in the heap is freed. +(allocated in the heap) by creating a `Box`. A box is a smart pointer to a +heap allocated value of type `T`. When a box goes out of scope, its destructor +is called, the inner object is destroyed, and the memory in the heap is freed. Boxed values can be dereferenced using the `*` operator; this removes one layer -of indirection. Alternatively, the `let box x = y` pattern can be used to -"unbox" `y` into `x`. +of indirection. {box.play} From 23e8a0db1654a726a9ba45f1772eb68c478903bf Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 11:46:01 -0500 Subject: [PATCH 0165/1122] raii --- examples/raii/raii.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/raii/raii.rs b/examples/raii/raii.rs index 03a59d4600..50bbba244f 100644 --- a/examples/raii/raii.rs +++ b/examples/raii/raii.rs @@ -1,12 +1,12 @@ fn create_box() { - // Allocate an integer in the heap + // Allocate an integer on the heap let _function_box = Box::new(3i32); // `_function_box` gets destroyed here, memory gets freed } fn main() { - // Allocate an integer in the heap + // Allocate an integer on the heap let _boxed_int = Box::new(5i32); // new (smaller) scope From 9bda14b76d9158b403dd73e939bbb296156ee003 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 12:06:04 -0500 Subject: [PATCH 0166/1122] borrow --- examples/borrow/borrow.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/borrow/borrow.rs b/examples/borrow/borrow.rs index 92041d59ab..5eea9acdbf 100644 --- a/examples/borrow/borrow.rs +++ b/examples/borrow/borrow.rs @@ -3,24 +3,24 @@ fn eat_box(boxed_int: Box) { println!("destroying box that contains {}", boxed_int); } -// This function borrows the box -fn peep_inside_box(borrowed_box: &Box) { - println!("This box contains {}", borrowed_box); +// This function borrows an i32 instead +fn peep_inside_box(borrowed_int: &i32) { + println!("This int is: {}", borrowed_int); } fn main() { // A boxed integer let boxed_int = Box::new(5); - // Borrow the box, ownership is not taken + // Borrow the contents of the box, ownership is not taken peep_inside_box(&boxed_int); - // The box can be borrowed again + // The contents can be borrowed again peep_inside_box(&boxed_int); { // Take a reference to the data contained inside the box - let _ref_to_int: &i32 = &*boxed_int; + let _ref_to_int: &i32 = &boxed_int; // Error! Can't destroy boxed_int, while the inner value has been // borrowed From 1c0a780bb383c37611c0216e959b2c293e4a0f59 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 13:07:02 -0500 Subject: [PATCH 0167/1122] some lifetime nits --- examples/lifetime/input.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/lifetime/input.md b/examples/lifetime/input.md index 8456e0d6cf..39190cb957 100644 --- a/examples/lifetime/input.md +++ b/examples/lifetime/input.md @@ -1,12 +1,10 @@ The compiler enforces valid borrowing using its borrow checker. To accomplish -this, it keeps track of two things: -* The *lifetime* of objects, and -* The scope of blocks +this, it keeps track of the scope of blocks. The lifetime of an object starts when the object is created and ends when it goes out of scope (i.e. it gets destroyed, because of the RAII discipline). -A lifetime looks like this: `'burrito`, which reads as: "lifetime burrito". +A lifetime looks like this: `'burrito`, which reads as: "the lifetime burrito". All references actually have a type signature of the form `&'a T`, where `'a` is the lifetime of the *referenced* object. The compiler takes care of @@ -15,7 +13,7 @@ inserting the lifetime part `'a` so we can simply type annotate references with For example: -``` rust +```rust let integer: int = 5; let ref_to_int: &int = &integer; ``` From 069ebd36c0c8236b5d4b488e881cd054248fccd0 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 25 Feb 2015 13:07:36 -0500 Subject: [PATCH 0168/1122] rephrase tuple indexing Fixes #333 --- examples/tuples/tuples.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tuples/tuples.rs b/examples/tuples/tuples.rs index 835408c5d2..646dfcec75 100644 --- a/examples/tuples/tuples.rs +++ b/examples/tuples/tuples.rs @@ -13,7 +13,7 @@ fn main() { 0.1f32, 0.2f64, 'a', true); - // Values can be extracted from the tuple using the `.N` syntax + // Values can be extracted from the tuple using tuple indexing println!("long tuple first value: {}", long_tuple.0); println!("long tuple second value: {}", long_tuple.1); From a03dc19a0cca2ef3566f91c29dd5d7b935bf9cd0 Mon Sep 17 00:00:00 2001 From: Chellygel Date: Wed, 25 Feb 2015 22:48:52 -0600 Subject: [PATCH 0169/1122] Removed the extra s from bindings --- examples/type/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/type/input.md b/examples/type/input.md index 149cdcb927..c26df5cb06 100644 --- a/examples/type/input.md +++ b/examples/type/input.md @@ -1,4 +1,4 @@ -Rust provides type safety via static typing. Variable bindingss can be type +Rust provides type safety via static typing. Variable bindings can be type annotated when declared. However, in most cases, the compiler will be able to infer the type of the variable from the context, heavily reducing the annotation burden. From cc4c9000f78b00c12adef1a186a01de1066c97ae Mon Sep 17 00:00:00 2001 From: WrekitRalf Date: Thu, 26 Feb 2015 13:48:57 +0000 Subject: [PATCH 0170/1122] Results: Fixing text wrapping bug Changed white-space on results to normal to stop text overflowing. --- node_modules/gitbook-plugin-rust-playpen/book/editor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index 4eee7e902e..b45d59da49 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -28,7 +28,7 @@ display: none; border-radius: 4px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - white-space: pre; + white-space: normal; } #reset-code { From 1874422cab07eb64f84520908c086c74b620298b Mon Sep 17 00:00:00 2001 From: Zach Sitler Date: Tue, 3 Mar 2015 22:00:07 -0700 Subject: [PATCH 0171/1122] closures: fix obsolete syntax `&:`. --- examples/closures/closures.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/closures/closures.rs b/examples/closures/closures.rs index 11129205ce..c41311488b 100644 --- a/examples/closures/closures.rs +++ b/examples/closures/closures.rs @@ -1,7 +1,7 @@ fn main() { let captured_value = 7u32; - let closure = |&:argument| { + let closure = |argument| { println!("I captured this: {}", captured_value); println!("Argument passed was: {}", argument); From 4a25c34947b2a1c7f308acbb68646686d517fb7f Mon Sep 17 00:00:00 2001 From: Walker Henderson Date: Sat, 7 Mar 2015 23:49:24 -0600 Subject: [PATCH 0172/1122] Changed lifetime names to reflect comments --- examples/lifetime/borrow/borrow.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/lifetime/borrow/borrow.rs b/examples/lifetime/borrow/borrow.rs index 8e5f2cc869..006f12ac97 100644 --- a/examples/lifetime/borrow/borrow.rs +++ b/examples/lifetime/borrow/borrow.rs @@ -1,15 +1,15 @@ -// FIXME To see the "real" compiler error, change both `&'b` and `&'e` into `&` +// FIXME To see the "real" compiler error, change both `&'c` and `&'d` into `&` fn main() { // `'main` starts ────────────────────────────────────────────┐ let stack_integer: i32 = 5; // `'a` starts ─────────────────────────┐ │ let boxed_integer = Box::new(4); // `'b` starts ──────────────────┐ │ │ // │ │ │ // This is a valid operation │ │ │ - let ref_to_box: &'b i32 = &*boxed_integer; // `'c` starts ──────┐ │ │ │ + let ref_to_box: &'c i32 = &*boxed_integer; // `'c` starts ──────┐ │ │ │ // │ │ │ │ // The compiler forbids this operation, because │ │ │ │ // `ref_to_another_box` would become a dangling pointer │ │ │ │ - let ref_to_another_box: &'e i32 = { // `'let` `'d` start ───┬─┐ │ │ │ │ + let ref_to_another_box: &'d i32 = { // `'let` `'d` start ───┬─┐ │ │ │ │ let another_boxed_integer = Box::new(3); // ──────────┐ │ │ │ │ │ │ // ^ `e` starts │ │ │ │ │ │ │ &*another_boxed_integer // │ │ │ │ │ │ │ From 1a169efbb1a9ea81771d2651103c108368b44441 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sun, 8 Mar 2015 13:38:53 -0400 Subject: [PATCH 0173/1122] Update to the latest nightly. This also un-pins the version, so we can go back to being current with the nightly. --- .travis.yml | 3 +- Cargo.lock | 8 +-- examples/arg/args.rs | 2 +- examples/arg/getopts/echo.rs | 2 +- examples/arg/getopts/testopt.rs | 2 +- examples/arg/matching/match_args.rs | 2 - examples/file/create/create.rs | 15 +++-- examples/file/open/open.rs | 14 +++-- examples/fs/fs.rs | 85 ++++++++++++++++------------- examples/iter/iter.rs | 2 + examples/path/path.rs | 17 ++---- examples/process/pipe/pipe.rs | 29 +++++----- examples/process/process.rs | 36 ++++-------- examples/process/wait/wait.rs | 4 +- examples/sockets/client.rs | 33 ----------- examples/sockets/common.rs | 1 - examples/sockets/input.md | 34 ------------ examples/sockets/server.rs | 32 ----------- examples/structure.json | 1 - src/example.rs | 26 +++++---- src/file.rs | 72 +++++++++--------------- src/main.rs | 4 +- src/markdown.rs | 37 +++++++------ 23 files changed, 166 insertions(+), 295 deletions(-) delete mode 100644 examples/sockets/client.rs delete mode 100644 examples/sockets/common.rs delete mode 100644 examples/sockets/input.md delete mode 100644 examples/sockets/server.rs diff --git a/.travis.yml b/.travis.yml index 6682578bcf..de53f705b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ language: node_js sudo: true install: - - curl -L -s https://static.rust-lang.org/rustup.sh -O - - sudo sh -c 'sh rustup.sh --date=2015-02-22' > /dev/null + - curl -L https://static.rust-lang.org/rustup.sh | sudo sh script: - rustc --version diff --git a/Cargo.lock b/Cargo.lock index 628f5f4285..fcca0780fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.2.15" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/examples/arg/args.rs b/examples/arg/args.rs index 6596648926..891b9e475c 100644 --- a/examples/arg/args.rs +++ b/examples/arg/args.rs @@ -1,4 +1,4 @@ -#![feature(env)] +#![feature(collections)] use std::env; diff --git a/examples/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs index 581261ea6b..46c0576398 100644 --- a/examples/arg/getopts/echo.rs +++ b/examples/arg/getopts/echo.rs @@ -1,7 +1,7 @@ #![feature(old_io)] #![feature(rustc_private)] -#![feature(env)] #![feature(collections)] +#![feature(exit_status)] extern crate getopts; diff --git a/examples/arg/getopts/testopt.rs b/examples/arg/getopts/testopt.rs index ab457e8107..645a0e5409 100644 --- a/examples/arg/getopts/testopt.rs +++ b/examples/arg/getopts/testopt.rs @@ -1,6 +1,6 @@ #![feature(rustc_private)] #![feature(collections)] -#![feature(env)] +#![feature(exit_status)] extern crate getopts; diff --git a/examples/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs index 6efcd72389..4ef4d477d3 100644 --- a/examples/arg/matching/match_args.rs +++ b/examples/arg/matching/match_args.rs @@ -1,5 +1,3 @@ -#![feature(env)] - use std::env; fn increase(number: i32) { diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 2d6eebd612..85e7a17528 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,7 +1,5 @@ -#![feature(old_io)] #![feature(old_path)] - -use std::old_io::File; +#![feature(io)] static LOREM_IPSUM: &'static str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod @@ -12,20 +10,25 @@ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "; +use std::io::prelude::*; +use std::fs::File; + fn main() { let path = Path::new("out/lorem_ipsum.txt"); let display = path.display(); // Open a file in write-only mode, returns `IoResult` let mut file = match File::create(&path) { - Err(why) => panic!("couldn't create {}: {}", display, why.desc), + Err(why) => panic!("couldn't create {}: {}", + display, + why.description()), Ok(file) => file, }; // Write the `LOREM_IPSUM` string to `file`, returns `IoResult<()>` - match file.write_str(LOREM_IPSUM) { + match file.write_all(LOREM_IPSUM.as_bytes()) { Err(why) => { - panic!("couldn't write to {}: {}", display, why.desc) + panic!("couldn't write to {}: {}", display, why.description()) }, Ok(_) => println!("successfully wrote to {}", display), } diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index 6b0bc6872c..02b433a8b4 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,7 +1,8 @@ -#![feature(old_io)] #![feature(old_path)] +#![feature(io)] -use std::old_io::File; +use std::io::prelude::*; +use std::fs::File; fn main() { // Create a path to the desired file @@ -11,14 +12,15 @@ fn main() { // Open the path in read-only mode, returns `IoResult` let mut file = match File::open(&path) { // The `desc` field of `IoError` is a string that describes the error - Err(why) => panic!("couldn't open {}: {}", display, why.desc), + Err(why) => panic!("couldn't open {}: {}", display, why.description()), Ok(file) => file, }; // Read the file contents into a string, returns `IoResult` - match file.read_to_string() { - Err(why) => panic!("couldn't read {}: {}", display, why.desc), - Ok(string) => print!("{} contains:\n{}", display, string), + let mut s = String::new(); + match file.read_to_string(&mut s) { + Err(why) => panic!("couldn't read {}: {}", display, why.description()), + Ok(_) => print!("{} contains:\n{}", display, s), } // `file` goes out of scope, and the "hello.txt" file gets closed diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 925233988a..1619f15fcc 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -1,73 +1,82 @@ -#![feature(old_io)] +#![feature(io)] #![feature(old_path)] +#![feature(fs_walk)] -use std::old_io::fs; -use std::old_io::fs::PathExtensions; -use std::old_io::{File, IoResult, USER_RWX}; +use std::io; +use std::io::prelude::*; +use std::fs; +use std::fs::File; +use std::fs::OpenOptions; // A simple implementation of `% cat path` -fn cat(path: &Path) -> IoResult { - File::open(path).and_then(|mut f| f.read_to_string()) +fn cat(path: &Path) -> io::Result { + let mut f = try!(File::open(path)); + let mut s = String::new(); + match f.read_to_string(&mut s) { + Ok(o) => Ok(s), + Err(e) => Err(e), + } } // A simple implementation of `% echo s > path` -fn echo(s: &str, path: &Path) -> IoResult<()> { - File::create(path).and_then(|mut f| f.write_str(s)) +fn echo(s: &str, path: &Path) -> io::Result<()> { + let mut f = try!(File::create(path)); + + f.write_all(s.as_bytes()) } // A simple implementation of `% touch path` (ignores existing files) -fn touch(path: &Path) -> IoResult<()> { - if !path.exists() { - File::create(path).and_then(|_| Ok(())) - } else { - Ok(()) +fn touch(path: &Path) -> io::Result<()> { + match OpenOptions::new().create(true).open(path) { + Ok(_) => Ok(()), + Err(e) => Err(e), } } fn main() { println!("`mkdir a`"); - // Create a directory, returns `IoResult<()>` - match fs::mkdir(&Path::new("a"), USER_RWX) { - Err(why) => println!("! {:?}", why.kind), + // Create a directory, returns `io::Result<()>` + match fs::create_dir(&Path::new("a")) { + Err(why) => println!("! {:?}", why.kind()), Ok(_) => {}, } println!("`echo hello > a/b.txt`"); // The previous match can be simplified using the `unwrap_or_else` method echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + println!("! {:?}", why.kind()); }); println!("`mkdir -p a/c/d`"); - // Recursively create a directory, returns `IoResult<()>` - fs::mkdir_recursive(&Path::new("a/c/d"), USER_RWX).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + // Recursively create a directory, returns `io::Result<()>` + fs::create_dir_all(&Path::new("a/c/d")).unwrap_or_else(|why| { + println!("! {:?}", why.kind()); }); println!("`touch a/c/e.txt`"); touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + println!("! {:?}", why.kind()); }); println!("`ln -s ../b.txt a/c/b.txt`"); - // Create a symbolic link, returns `IoResult<()>` - fs::symlink(&Path::new("../b.txt"), + // Create a symbolic link, returns `io::Result<()>` + fs::soft_link(&Path::new("../b.txt"), &Path::new("a/c/b.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + println!("! {:?}", why.kind()); }); println!("`cat a/c/b.txt`"); match cat(&Path::new("a/c/b.txt")) { - Err(why) => println!("! {:?}", why.kind), + Err(why) => println!("! {:?}", why.kind()), Ok(s) => println!("> {}", s), } println!("`ls a`"); - // Read the contents of a directory, returns `IoResult>` - match fs::readdir(&Path::new("a")) { - Err(why) => println!("! {:?}", why.kind), - Ok(paths) => for path in paths.iter() { - println!("> {}", path.display()); + // Read the contents of a directory, returns `io::Result>` + match fs::read_dir(&Path::new("a")) { + Err(why) => println!("! {:?}", why.kind()), + Ok(paths) => for path in paths { + println!("> {:?}", path.unwrap().path()); }, } @@ -75,21 +84,21 @@ fn main() { // Recursively walk over the contents of a directory, returns // `Directories`, which implements the `Iterator trait match fs::walk_dir(&Path::new("a")) { - Err(why) => println!("! {:?}", why.kind), + Err(why) => println!("! {:?}", why.kind()), Ok(paths) => for path in paths { - println!("> {}", path.display()); + println!("> {:?}", path.unwrap().path()); }, } println!("`rm a/c/e.txt`"); - // Remove a file, returns `IoResult<()>` - fs::unlink(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + // Remove a file, returns `io::Result<()>` + fs::remove_file(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { + println!("! {:?}", why.kind()); }); println!("`rmdir a/c/d`"); - // Remove an empty directory, returns `IoResult<()>` - fs::rmdir(&Path::new("a/c/d")).unwrap_or_else(|why| { - println!("! {:?}", why.kind); + // Remove an empty directory, returns `io::Result<()>` + fs::remove_dir(&Path::new("a/c/d")).unwrap_or_else(|why| { + println!("! {:?}", why.kind()); }); } diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index fe8d47a165..076ddd66ef 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -1,3 +1,5 @@ +#![feature(core)] + struct Fibonacci { curr: u32, next: u32, diff --git a/examples/path/path.rs b/examples/path/path.rs index 21d26513ec..92100175c2 100644 --- a/examples/path/path.rs +++ b/examples/path/path.rs @@ -1,7 +1,8 @@ -#![feature(old_path)] -#![feature(old_io)] +#![feature(path)] +#![feature(path_ext)] -use std::old_io::fs::PathExtensions; +use std::path::Path; +use std::fs::PathExt; fn main() { // Create a `Path` from an `&'static str` @@ -25,20 +26,12 @@ fn main() { println!("{} is a directory", display); } - // `stat` returns an IoResult === Result - let stat = match path.stat() { - Err(why) => panic!("{}", why.desc), - Ok(stat) => stat, - }; - - println!("{} size is {} bytes", display, stat.size); - // `join` merges a path with a byte container using the OS specific // separator, and returns the new path let new_path = path.join("a").join("b"); // Convert the path into a string slice - match new_path.as_str() { + match new_path.to_str() { None => panic!("new path is not a valid UTF-8 sequence"), Some(s) => println!("new path is {}", s), } diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index 340c25cf79..dd833175c2 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,28 +1,23 @@ -#![feature(old_io)] +#![feature(io)] -use std::old_io::process::Command; +use std::process::Command; +use std::io::prelude::*; static PANGRAM: &'static str = "the quick brown fox jumped over the lazy dog\n"; fn main() { // Spawn the `wc` command - let mut process = match Command::new("wc").spawn() { - Err(why) => panic!("couldn't spawn wc: {}", why.desc), + let process = match Command::new("wc").spawn() { + Err(why) => panic!("couldn't spawn wc: {}", why.description()), Ok(process) => process, }; { - // The `stdin` field has type `Option` - // `take` will take the value out of an `Option`, leaving `None` in - // its place. - // - // Note that we take ownership of `stdin` here - let mut stdin = process.stdin.take().unwrap(); - // Write a string to the stdin of `wc` - match stdin.write_str(PANGRAM) { - Err(why) => panic!("couldn't write to wc stdin: {}", why.desc), + match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { + Err(why) => panic!("couldn't write to wc stdin: {}", + why.description()), Ok(_) => println!("sent pangram to wc"), } @@ -34,8 +29,10 @@ fn main() { // The `stdout` field also has type `Option` // the `as_mut` method will return a mutable reference to the value // wrapped in a `Some` variant - match process.stdout.as_mut().unwrap().read_to_string() { - Err(why) => panic!("couldn't read wc stdout: {}", why.desc), - Ok(string) => print!("wc responded with:\n{}", string), + let mut s = String::new(); + match process.stdout.unwrap().read_to_string(&mut s) { + Err(why) => panic!("couldn't read wc stdout: {}", + why.description()), + Ok(_) => print!("wc responded with:\n{}", s), } } diff --git a/examples/process/process.rs b/examples/process/process.rs index 14164ba4e3..62562612f8 100644 --- a/examples/process/process.rs +++ b/examples/process/process.rs @@ -1,31 +1,19 @@ -#![feature(old_io)] - -use std::old_io::process::{Command,ProcessOutput}; +use std::process::Command; fn main() { - // Initial command `rustc` - let mut cmd = Command::new("rustc"); - // append the "--version" flag to the command - cmd.arg("--version"); + let output = Command::new("rustc") + .arg("--version") + .output().unwrap_or_else(|e| { + panic!("failed to execute process: {}", e) + }); - // The `output` method will spawn `rustc --version`, wait until the process - // finishes and return the output of the process - match cmd.output() { - Err(why) => panic!("couldn't spawn rustc: {}", why.desc), - // Destructure `ProcessOutput` - Ok(ProcessOutput { error: err, output: out, status: exit }) => { - // Check if the process succeeded, i.e. the exit code was 0 - if exit.success() { - // `out` has type `Vec`, convert it to a UTF-8 `$str` - let s = String::from_utf8_lossy(&out); + if output.status.success() { + let s = String::from_utf8_lossy(&output.stdout); - print!("rustc succeeded and stdout was:\n{}", s); - } else { - // `err` also has type `Vec` - let s = String::from_utf8_lossy(&err); + print!("rustc succeeded and stdout was:\n{}", s); + } else { + let s = String::from_utf8_lossy(&output.stderr); - print!("rustc failed and stderr was:\n{}", s); - } - }, + print!("rustc failed and stderr was:\n{}", s); } } diff --git a/examples/process/wait/wait.rs b/examples/process/wait/wait.rs index 8400a21728..37cbf9276e 100644 --- a/examples/process/wait/wait.rs +++ b/examples/process/wait/wait.rs @@ -1,6 +1,4 @@ -#![feature(old_io)] - -use std::old_io::process::Command; +use std::process::Command; fn main() { let _process = Command::new("sleep").arg("5").spawn(); diff --git a/examples/sockets/client.rs b/examples/sockets/client.rs deleted file mode 100644 index 41bb6f5c50..0000000000 --- a/examples/sockets/client.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![feature(old_io)] -#![feature(old_path)] -#![feature(env)] - -use std::env; -use common::SOCKET_PATH; -use std::old_io::net::pipe::UnixStream; - -mod common; - -fn main() { - // `args` returns the arguments passed to the program - let args: Vec = env::args().map(|x| x.to_string()) - .collect(); - let socket = Path::new(SOCKET_PATH); - - // First argument is the message to be sent - if args.len() != 2 { - panic!("wrong number of arguments"); - } - - // Connect to socket - let mut stream = match UnixStream::connect(&socket) { - Err(_) => panic!("server is not running"), - Ok(stream) => stream, - }; - - // Send message - match stream.write_str(&args[1]) { - Err(_) => panic!("couldn't send message"), - Ok(_) => {} - } -} diff --git a/examples/sockets/common.rs b/examples/sockets/common.rs deleted file mode 100644 index 04b94028e8..0000000000 --- a/examples/sockets/common.rs +++ /dev/null @@ -1 +0,0 @@ -pub static SOCKET_PATH: &'static str = "loopback-socket"; diff --git a/examples/sockets/input.md b/examples/sockets/input.md deleted file mode 100644 index f88e85067a..0000000000 --- a/examples/sockets/input.md +++ /dev/null @@ -1,34 +0,0 @@ -Inter-Process Communication (IPC) for client-server applications can be -accomplished using -[UNIX sockets][unix-sockets]. - -Both client and server need to use the same path for the socket. - -{common.rs} - -The client program: - -{client.rs} - -The server program: - -{server.rs} - -Let's test the programs - -``` -$ rustc client.rs; rustc server.rs - -# Terminal 1 -$ ./server -Server started, waiting for clients - -# Terminal 2 -$ ./client hello - -# Terminal 1 -Server started, waiting for clients -Client said: hello -``` - -[unix-sockets]: http://en.wikipedia.org/wiki/Unix_domain_socket diff --git a/examples/sockets/server.rs b/examples/sockets/server.rs deleted file mode 100644 index 84973916d1..0000000000 --- a/examples/sockets/server.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![feature(old_io)] -#![feature(old_path)] - -use common::SOCKET_PATH; -use std::old_io::fs; -use std::old_io::fs::PathExtensions; -use std::old_io::net::pipe::UnixListener; -use std::old_io::{Acceptor,Listener}; - -mod common; - -fn main() { - let socket = Path::new(SOCKET_PATH); - - // Delete old socket if necessary - if socket.exists() { - fs::unlink(&socket).unwrap(); - } - - // Bind to socket - let stream = match UnixListener::bind(&socket) { - Err(_) => panic!("failed to bind socket"), - Ok(stream) => stream, - }; - - println!("Server started, waiting for clients"); - - // Iterate over clients, blocks if no client available - for mut client in stream.listen().incoming() { - println!("Client said: {}", client.read_to_string().unwrap()); - } -} diff --git a/examples/structure.json b/examples/structure.json index e8a8e3684e..3766b3e11d 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -102,7 +102,6 @@ { "id": "threads", "title": "Threads", "children": null }, { "id": "channels", "title": "Channels", "children": null }, { "id": "timers", "title": "Timers", "children": null }, - { "id": "sockets", "title": "Unix sockets", "children": null }, { "id": "result", "title": "`Result`", "children": [ { "id": "try", "title": "`try!`", "children": null } ] }, diff --git a/src/example.rs b/src/example.rs index 3f8e32e226..d0727844df 100644 --- a/src/example.rs +++ b/src/example.rs @@ -1,9 +1,11 @@ -use file; use markdown::Markdown; use rustc_serialize::{Decodable,json}; use std::iter::AdditiveIterator; use std::iter::repeat; use std::sync::mpsc; +use std::io::prelude::*; +use std::fs; +use std::fs::File; #[derive(RustcDecodable)] pub struct Example { @@ -14,15 +16,17 @@ pub struct Example { impl Example { pub fn get_list() -> Vec { - match file::read(&Path::new("examples/structure.json")) { - Err(why) => panic!("{}", why), - Ok(string) => match json::Json::from_str(&string) { - Err(_) => panic!("structure.json is not valid json"), - Ok(json) => { - match Decodable::decode(&mut json::Decoder::new(json)) { - Err(_) => panic!("error decoding structure.json"), - Ok(examples) => examples, - } + + let mut f = File::open(&Path::new("examples/structure.json")).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + + match json::Json::from_str(&s) { + Err(_) => panic!("structure.json is not valid json"), + Ok(json) => { + match Decodable::decode(&mut json::Decoder::new(json)) { + Err(_) => panic!("error decoding structure.json"), + Ok(examples) => examples, } } } @@ -74,7 +78,7 @@ impl Example { Some(ref children) => { let path = Path::new(format!("stage/{}/{}", prefix, id)); - file::mkdir(&path); + fs::create_dir_all(&path).unwrap(); for (i, example) in children.iter().enumerate() { let tx = tx.clone(); diff --git a/src/file.rs b/src/file.rs index fced155e32..7801714c32 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,65 +1,43 @@ use std::env; -use std::old_io::USER_RWX; -use std::old_io::fs; -use std::old_io::process::{Command,ProcessOutput}; -use std::old_io::{File,Truncate,Write}; +use std::process::Command; +use std::io::prelude::*; +use std::io; +use std::fs; +use std::fs::File; pub fn mkdir(path: &Path) { - match fs::mkdir_recursive(path, USER_RWX) { + match fs::create_dir_all(path) { Err(_) => {}, Ok(_) => {}, } } -pub fn read(path: &Path) -> Result { - match File::open(path) { - Err(_) => Err(format!("couldn't open {}", path.display())), - Ok(mut file) => match file.read_to_string() { - Err(_) => Err(format!("couldn't read {}", path.display())), - Ok(string) => Ok(string), - } - } -} - pub fn run(prefix: &str, id: &str, src: &str) -> Result { let cwd = env::current_dir().unwrap(); // Assume that the current working directory actually exists - let out_dir = cwd.join(format!("bin/{}/{}", prefix, id)); - - let mut cmd = Command::new("rustc"); - cmd.cwd(&Path::new(format!("examples/{}/{}", prefix, id))); - cmd.arg(format!("{}.rs", src)); - cmd.arg("--out-dir"); - cmd.arg(out_dir); - - match cmd.output() { - Err(_) => return Err(format!("couldn't find rustc")), - Ok(p) => if !p.status.success() { - return Ok(String::from_utf8(p.error).unwrap()); - }, - } + let out_dir = cwd.join(&format!("bin/{}/{}", prefix, id)); + + match Command::new("rustc") + .current_dir(&Path::new(format!("examples/{}/{}", prefix, id))) + .arg(&format!("{}.rs", src)) + .arg("--out-dir") + .arg(&out_dir) + .output() { + Ok(o) => o, + Err(e) => { return Ok(e.to_string()) }, + }; let executable = Path::new(format!("./bin/{}/{}/{}", prefix, id, src)); - match Command::new(&executable).output() { - Err(_) => Err(format!("couldn't find {}", executable.display())), - Ok(ProcessOutput { error, output, status }) => { - let mut s = String::from_utf8(output).unwrap(); - if !status.success() { - s.push_str(&String::from_utf8(error).unwrap()); - } + let output = match Command::new(&executable).output() { + Ok(o) => o, + Err(e) => { return Ok(e.to_string()) }, + }; - Ok(s) - } - } + Ok(String::from_utf8(output.stdout).unwrap()) } -pub fn write(path: &Path, string: &str) -> Result<(), String> { - match File::open_mode(path, Truncate, Write) { - Err(_) => Err(format!("couldn't open {}", path.display())), - Ok(mut file) => match file.write_str(string) { - Err(_) => Err(format!("couldn't write {}", path.display())), - Ok(_) => Ok(()), - } - } +pub fn write(path: &Path, string: &str) -> io::Result<()> { + let mut f = try!(File::create(path)); + f.write_all(string.as_bytes()) } diff --git a/src/main.rs b/src/main.rs index b7f09cff0e..95b03168bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ -#![feature(old_io)] #![feature(old_path)] -#![feature(env)] #![feature(core)] +#![feature(io)] +#![feature(path)] #![deny(warnings)] #![feature(int_uint)] diff --git a/src/markdown.rs b/src/markdown.rs index 7c57647fa1..f195f3b2fd 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -2,6 +2,8 @@ use file; use playpen; use std::iter::repeat; use regex::Regex; +use std::io::prelude::*; +use std::fs::File; pub struct Markdown<'a, 'b> { content: String, @@ -27,7 +29,11 @@ impl<'a, 'b> Markdown<'a, 'b> { -> Result, String> { let path = Path::new(format!("examples/{}/{}/input.md", prefix, id)); - let body = try!(file::read(&path)); + + let mut f = File::open(&path).unwrap(); + let mut body = String::new(); + f.read_to_string(&mut body).unwrap(); + let version = number.iter().map(|x| { format!("{}", x) }).collect::>().connect("."); @@ -59,15 +65,11 @@ impl<'a, 'b> Markdown<'a, 'b> { let src = captures.at(1).unwrap(); let input = format!("{{{}}}", src); let p = format!("examples/{}/{}/{}", prefix, id, src); - let output = match file::read(&Path::new(&p)) { - Err(_) => { - return Err(format!("{} not found", p)); - }, - Ok(string) => { - format!("``` rust\n// {}\n{}```", - src, string) - } - }; + + let mut f = File::open(&Path::new(&p)).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + let output = format!("``` rust\n// {}\n{}```", src, s); table.push((input, output)) } @@ -139,14 +141,12 @@ impl<'a, 'b> Markdown<'a, 'b> { let input = format!("{{{}.play}}", srcbase); let src = format!("{}.rs", srcbase); let p = format!("examples/{}/{}/{}", prefix, id, src); - let output = match file::read(&Path::new(&p)) { - Err(_) => { - return Err(format!("{} not found", p)); - }, - Ok(source) => { - playpen::editor(&source) - } - }; + + let mut f = File::open(&Path::new(&p)).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + + let output = playpen::editor(&s); table.push((input, output)) } @@ -165,5 +165,6 @@ impl<'a, 'b> Markdown<'a, 'b> { let path = Path::new(format!("stage/{}/{}.md", self.prefix, self.id)); file::write(&path, &self.content) + .map_err(|e| e.description().to_string()) } } From 5eb9daf4847bf828d35f2006dc88cba7e728b4fb Mon Sep 17 00:00:00 2001 From: Nick Platt Date: Tue, 10 Mar 2015 22:45:47 -0400 Subject: [PATCH 0174/1122] Update use of std::env::args in arg chapter --- examples/arg/args.rs | 7 ++++--- examples/arg/getopts/echo.rs | 3 +-- examples/arg/getopts/input.md | 2 +- examples/arg/getopts/testopt.rs | 3 +-- examples/arg/input.md | 6 +++--- examples/arg/matching/input.md | 4 ++-- examples/arg/matching/match_args.rs | 5 +++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/arg/args.rs b/examples/arg/args.rs index 891b9e475c..647583b471 100644 --- a/examples/arg/args.rs +++ b/examples/arg/args.rs @@ -3,12 +3,13 @@ use std::env; fn main() { - let args: Vec = env::args().map(|x| x.to_string()) - .collect(); + let args: Vec = env::args().collect(); + // The first argument is the path that was used to call the program. println!("My path is {}.", args[0]); + // The rest of the arguments are the passed command line parameters. // Call the program like this: - // $ ./args arg1 arg2 + // $ ./args arg1 arg2 println!("I got {:?} arguments: {:?}.", args.len() - 1, args.tail()); } diff --git a/examples/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs index 46c0576398..cd565ac404 100644 --- a/examples/arg/getopts/echo.rs +++ b/examples/arg/getopts/echo.rs @@ -11,8 +11,7 @@ use std::old_io::stdio; static VERSION: &'static str = "1.0.0"; fn main() { - let args: Vec = env::args().map(|x| x.to_string()) - .collect(); + let args: Vec = env::args().collect(); let ref program = args[0]; // Set possible flags. diff --git a/examples/arg/getopts/input.md b/examples/arg/getopts/input.md index 53a14d41ae..1ca22095d7 100644 --- a/examples/arg/getopts/input.md +++ b/examples/arg/getopts/input.md @@ -25,7 +25,7 @@ $ ./echo Hello, World! Hello, World! ``` -This is a simplified version of the `echo` implementation by +This is a simplified version of the implementation in [uutils](https://github.com/uutils/coreutils). diff --git a/examples/arg/getopts/testopt.rs b/examples/arg/getopts/testopt.rs index 645a0e5409..da40ab5a2e 100644 --- a/examples/arg/getopts/testopt.rs +++ b/examples/arg/getopts/testopt.rs @@ -7,8 +7,7 @@ extern crate getopts; use std::env; fn main() { - let args: Vec = env::args().map(|x| x.to_string()) - .collect(); + let args: Vec = env::args().collect(); let opts = [ getopts::optflag("a", "long_a", ""), diff --git a/examples/arg/input.md b/examples/arg/input.md index 8a2f0a2c06..407aa1967c 100644 --- a/examples/arg/input.md +++ b/examples/arg/input.md @@ -1,10 +1,10 @@ -The command line arguments can be accessed using `std::os::args`, which returns -a [vector](http://static.rust-lang.org/doc/master/std/vec/index.html) of strings: +The command line arguments can be accessed using `std::env::args`, which +returns an iterator that yields a String for each argument: {args.play} ``` $ ./args 1 2 3 My path is ./args. -I got 3 arguments: [1, 2, 3]. +I got 3 arguments: ["1", "2", "3"]. ``` diff --git a/examples/arg/matching/input.md b/examples/arg/matching/input.md index 0d97b55a57..e27533f9c4 100644 --- a/examples/arg/matching/input.md +++ b/examples/arg/matching/input.md @@ -25,6 +25,6 @@ $ ./match_args increase 42 43 ``` - -For implementing more complicated, unix-like command line interfaces see the `getopts` example. +The next example demonstrates `getopts` as a way to build more advanced, +unix-like command line interfaces. diff --git a/examples/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs index 4ef4d477d3..03cb415aa0 100644 --- a/examples/arg/matching/match_args.rs +++ b/examples/arg/matching/match_args.rs @@ -1,3 +1,5 @@ +#![feature(collections)] + use std::env; fn increase(number: i32) { @@ -17,8 +19,7 @@ match_args {{increase|decrease}} } fn main() { - let args: Vec = env::args().map(|x| x.to_string()) - .collect(); + let args: Vec = env::args().collect(); match &args[..] { // no arguments passed From 1369e3c731432a2232ac726ffef0922b07075356 Mon Sep 17 00:00:00 2001 From: Walker Henderson Date: Tue, 10 Mar 2015 22:35:44 -0500 Subject: [PATCH 0175/1122] Will now properly display newlines in successful output --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 77f2e809d1..d08a4b26e4 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -219,7 +219,11 @@ function handleResult(statusCode, message) { // Called on successful program run function handleSuccess(message) { resultDiv.style.backgroundColor = successColor; - resultDiv.innerHTML = escapeHTML(message); + var lines = message.split(newLineRegex); + message = lines.map(function(line) { + return escapeHTML(line); + }).join('
'); + resultDiv.innerHTML = message; } // Called when program run results in warning(s) From 73db016a859cb4fdeb2692228374ae3f89468a9b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 11 Mar 2015 22:44:43 -0400 Subject: [PATCH 0176/1122] Fix the build. Various stuff. --- Cargo.lock | 4 ++-- Makefile | 2 +- src/file.rs | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcca0780fc..8a7dd47b5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] diff --git a/Makefile b/Makefile index d62ead4e87..bee633080a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) ${STRICT} +RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) # ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/borrow/borrow.rs \ examples/borrow/freeze/freeze.rs \ diff --git a/src/file.rs b/src/file.rs index 7801714c32..0ed2f0bb03 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use std::env; use std::process::Command; use std::io::prelude::*; From 92b9bcf29465e84bf78fd39d46e4fa4a71b1ffad Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 11 Mar 2015 23:04:13 -0400 Subject: [PATCH 0177/1122] Fix warnings --- examples/arg/matching/match_args.rs | 2 -- examples/test/fail.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs index 03cb415aa0..3bf9e9e1a2 100644 --- a/examples/arg/matching/match_args.rs +++ b/examples/arg/matching/match_args.rs @@ -1,5 +1,3 @@ -#![feature(collections)] - use std::env; fn increase(number: i32) { diff --git a/examples/test/fail.rs b/examples/test/fail.rs index 28bb14dcce..15f4c85e2d 100644 --- a/examples/test/fail.rs +++ b/examples/test/fail.rs @@ -1,5 +1,5 @@ #[test] -#[should_fail] +#[should_panic] fn failing_test() { assert!(1i32 == 2i32); } From f6632d93172ebaf13096ee2819923053d37b2949 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 8 Mar 2015 17:21:28 -0400 Subject: [PATCH 0178/1122] Link to macro in hello world --- examples/hello/input.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/hello/input.md b/examples/hello/input.md index d8de3d239e..46dc674b13 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -2,7 +2,7 @@ This is the source code of the traditional Hello World program. {hello.play} -`println!` is a *macro* (we'll cover them later) that prints text to the +`println!` is a [*macro*][macros] that prints text to the console. A binary can be generated using the Rust compiler: `rustc`. @@ -17,3 +17,5 @@ $ rustc hello.rs $ ./hello Hello World! ``` + +[macros]: ./macros.html From c8df2eb1822fd203f2a49133cdcce22fe6fecb9b Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 15 Mar 2015 00:50:37 -0400 Subject: [PATCH 0179/1122] Cargo update --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a7dd47b5a..7640048751 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" From 860ec42ec398653b16424f7c163ae0a22e14a68b Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 15 Mar 2015 00:53:18 -0400 Subject: [PATCH 0180/1122] Fix the build: `use std::path::Path` remove a few `#![feature(...)]`s --- src/example.rs | 4 +++- src/file.rs | 7 +++++-- src/main.rs | 4 +--- src/markdown.rs | 15 ++++++++++----- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/example.rs b/src/example.rs index d0727844df..ee31e96393 100644 --- a/src/example.rs +++ b/src/example.rs @@ -6,6 +6,7 @@ use std::sync::mpsc; use std::io::prelude::*; use std::fs; use std::fs::File; +use std::path::Path; #[derive(RustcDecodable)] pub struct Example { @@ -76,7 +77,8 @@ impl Example { match self.children { None => {}, Some(ref children) => { - let path = Path::new(format!("stage/{}/{}", prefix, id)); + let path_str = &format!("stage/{}/{}", prefix, id); + let path = Path::new(path_str); fs::create_dir_all(&path).unwrap(); diff --git a/src/file.rs b/src/file.rs index 0ed2f0bb03..adb918c70e 100644 --- a/src/file.rs +++ b/src/file.rs @@ -6,6 +6,7 @@ use std::io::prelude::*; use std::io; use std::fs; use std::fs::File; +use std::path::Path; pub fn mkdir(path: &Path) { match fs::create_dir_all(path) { @@ -18,9 +19,10 @@ pub fn run(prefix: &str, id: &str, src: &str) -> Result { let cwd = env::current_dir().unwrap(); // Assume that the current working directory actually exists let out_dir = cwd.join(&format!("bin/{}/{}", prefix, id)); + let path_str = &format!("examples/{}/{}", prefix, id); match Command::new("rustc") - .current_dir(&Path::new(format!("examples/{}/{}", prefix, id))) + .current_dir(&Path::new(path_str)) .arg(&format!("{}.rs", src)) .arg("--out-dir") .arg(&out_dir) @@ -29,7 +31,8 @@ pub fn run(prefix: &str, id: &str, src: &str) -> Result { Err(e) => { return Ok(e.to_string()) }, }; - let executable = Path::new(format!("./bin/{}/{}/{}", prefix, id, src)); + let exec_str = &format!("./bin/{}/{}/{}", prefix, id, src); + let executable = Path::new(exec_str); let output = match Command::new(&executable).output() { Ok(o) => o, diff --git a/src/main.rs b/src/main.rs index 95b03168bc..4e2c85dc6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,4 @@ -#![feature(old_path)] #![feature(core)] -#![feature(io)] -#![feature(path)] #![deny(warnings)] #![feature(int_uint)] @@ -14,6 +11,7 @@ extern crate "rustc-serialize" as rustc_serialize; use example::Example; use std::thread; use std::sync::mpsc; +use std::path::Path; mod example; mod file; diff --git a/src/markdown.rs b/src/markdown.rs index f195f3b2fd..54ad864267 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -4,6 +4,8 @@ use std::iter::repeat; use regex::Regex; use std::io::prelude::*; use std::fs::File; +use std::path::Path; +use std::error::Error; pub struct Markdown<'a, 'b> { content: String, @@ -28,7 +30,8 @@ impl<'a, 'b> Markdown<'a, 'b> { fn new(number: &[uint], id: &'a str, title: &str, prefix: &'b str) -> Result, String> { - let path = Path::new(format!("examples/{}/{}/input.md", prefix, id)); + let path_str = &format!("examples/{}/{}/input.md", prefix, id); + let path = Path::new(path_str); let mut f = File::open(&path).unwrap(); let mut body = String::new(); @@ -89,9 +92,10 @@ impl<'a, 'b> Markdown<'a, 'b> { let prefix = self.prefix; let r = Regex::new(r"\{(.*)\.out\}").unwrap(); - let dir = Path::new(format!("bin/{}/{}", prefix, id)); + let dir_str = &format!("bin/{}/{}", prefix, id); + let dir = Path::new(dir_str); - file::mkdir(&dir); + file::mkdir(dir); let mut table = Vec::new(); for line in self.content.lines() { @@ -162,9 +166,10 @@ impl<'a, 'b> Markdown<'a, 'b> { } fn save(&self) -> Result<(), String> { - let path = Path::new(format!("stage/{}/{}.md", self.prefix, self.id)); + let path_str = &format!("stage/{}/{}.md", self.prefix, self.id); + let path = Path::new(path_str); file::write(&path, &self.content) - .map_err(|e| e.description().to_string()) + .map_err(|ref e| Error::description(e).to_string()) } } From 65b9e944317001b246bf876797db88699b0a8b17 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 15 Mar 2015 23:23:27 -0400 Subject: [PATCH 0181/1122] Add more println! details --- examples/print/input.md | 29 +++++++++++-- examples/print/print.rs | 33 +++++++++----- examples/print/print_debug/debug.rs | 25 +++++++++++ examples/print/print_debug/input.md | 36 +++++++++++++++ examples/print/print_display/display.rs | 54 +++++++++++++++++++++++ examples/print/print_display/input.md | 58 +++++++++++++++++++++++++ examples/structure.json | 5 ++- 7 files changed, 224 insertions(+), 16 deletions(-) create mode 100644 examples/print/print_debug/debug.rs create mode 100644 examples/print/print_debug/input.md create mode 100644 examples/print/print_display/display.rs create mode 100644 examples/print/print_display/input.md diff --git a/examples/print/input.md b/examples/print/input.md index 7640dbfefa..e235cbde12 100644 --- a/examples/print/input.md +++ b/examples/print/input.md @@ -1,10 +1,31 @@ -The `println!` macro not only prints to the console, but is also capable of -formatting text and stringifying values. Plus, the formatting correctness will +Printing is handled by a series of [macros][macros] defined in [`std::fmt`][fmt] +some of which include: + +* `format!`: write formatted text to [`String`][string] +* `print!`: same as `format!` but the text is printed to the console. +* `println!`: same as `print!` but a newline is appended. + +All parse text in the same fashion. A plus is that the formatting correctness will be checked at compile time. {print.play} -For more information about formatting, take a look at -[std::fmt][fmt]. +[`std::fmt`][fmt] contains many [`trait`s][traits] which govern the display +of text. The base form of two important ones are listed below: + +* `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes. +* `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user +friendly fashion. + +Here, `fmt::Display` was used because the std library provides implementations +for these types. To print text for custom types, more steps are required. + +### See also: +[`std::fmt`][fmt], [macros][macros], [`struct`][structs], +and [`trait`s][traits] [fmt]: http://doc.rust-lang.org/std/fmt/ +[macros]: ./macros.html +[string]: ./str.html +[structs]: ./structs.html +[traits]: ./trait.html diff --git a/examples/print/print.rs b/examples/print/print.rs index 1d03e65d9e..9d978279da 100644 --- a/examples/print/print.rs +++ b/examples/print/print.rs @@ -1,23 +1,34 @@ fn main() { - // `{:?}` are placeholders for arguments that will be stringified. - println!("{:?} days", 31); + // In general, the `{}` will be automatically replaced with any + // arguments. These will be stringified. + println!("{} days", 31); // Without a suffix, 31 becomes an i32. You can change what type 31 is, - // with a suffix, and that is covered in the next chapter. + // with a suffix. - // The positional arguments can be reused along the template. - println!("{0:?}, this is {1:?}. {1:?}, this is {0:?}", "Alice", "Bob"); + // There are various optional patterns this works with. Positional + // arguments can be used. + println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); - // Named arguments can also be used. - println!("{subject:?} {verb:?} {predicate:?}", + // As can named arguments. + println!("{subject} {verb} {predicate}", predicate="over the lazy dog", subject="the quick brown fox", verb="jumps"); - // Special formatting can be specified in the place of the `?`. - println!("{:?} of {:b} people know binary, the other half don't", 1, 2); + // Special formatting can be specified after a `:`. + println!("{} of {:b} people know binary, the other half don't", 1, 2); - // Error! You are missing an argument. - println!("My name is {0:?}, {1:?} {0:?}", "Bond"); + // It will even check to make sure the correct number of arguments are + // used. + println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" + + // Create a structure which contains an `i32`. Name it `Structure`. + struct Structure(i32); + + // However, custom types such as this structure require more complicated + // handling. This will not work. + println!("This struct `{}` won't print...", Structure(3)); + // FIXME ^ Comment out this line. } diff --git a/examples/print/print_debug/debug.rs b/examples/print/print_debug/debug.rs new file mode 100644 index 0000000000..552aa346a9 --- /dev/null +++ b/examples/print/print_debug/debug.rs @@ -0,0 +1,25 @@ +// Derive the `fmt::Debug` implementation for `Structure`. `Structure` +// is a structure which contains a single `i32`. +#[derive(Debug)] +struct Structure(i32); + +// Put a `Structure` inside of the structure `Deep`. Make it printable +// also. +#[derive(Debug)] +struct Deep(Structure); + +fn main() { + // Printing with `{:?}` is similar to with `{}`. + println!("{:?} months in a year.", 12); + println!("{1:?} {0:?} is the {actor:?} name.", + "Slater", + "Christian", + actor="actor's"); + + // `Structure` is printable! + println!("Now {:?} will print!", Structure(3)); + + // The problem with `derive` is there is no control over how + // the results look. What if I was this to just show a `7`? + println!("Now {:?} will print!", Deep(Structure(7))); +} diff --git a/examples/print/print_debug/input.md b/examples/print/print_debug/input.md new file mode 100644 index 0000000000..a2abde3fb1 --- /dev/null +++ b/examples/print/print_debug/input.md @@ -0,0 +1,36 @@ +All types which want to use `std::fmt` formatting `trait`s require an +implementation to be printable. Automatic implementations are only provided +for types such as in the `std` library. All others *must* be manually +implemented somehow. + +The `fmt::Debug` `trait` makes this very straightforward. *All* types can +`derive` (automatically create) the `fmt::Debug` implementation. This is +not true for `fmt::Display` which must be manually implemented. + +```rust +// This structure cannot be printed either with `fmt::Display` or +// with `fmt::Debug` +struct UnPrintable(i32); + +// The `derive` attribute automatically creates the implementation +// required to make this `struct` printable with `fmt::Debug`. +#[derive(Debug)] +struct DebugPrintable(i32); +``` + +All std library types automatically are printable with `{:?}` too: + +{debug.play} + +So `fmt::Debug` definitely makes this printable but sacrifices some +elegance. Manually implementing `fmt::Display` will fix that. + +### See also: +[attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], +and [`struct`][structs] + +[attributes]: http://doc.rust-lang.org/reference.html#attributes +[derive]: ./trait/derive.html +[fmt]: http://doc.rust-lang.org/std/fmt/ +[structs]: ./structs.html + diff --git a/examples/print/print_display/display.rs b/examples/print/print_display/display.rs new file mode 100644 index 0000000000..d6e34d0518 --- /dev/null +++ b/examples/print/print_display/display.rs @@ -0,0 +1,54 @@ +use std::fmt; // Import `fmt` + +// A structure holding two numbers. `Debug` will be derived so the results can +// be contrasted with `Display`. +#[derive(Debug)] +struct MinMax(i64, i64); + +// Implement `Display` for `MinMax`. +impl fmt::Display for MinMax { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Use `self.number` to refer to each positional data point. + write!(f, "({}, {})", self.0, self.1) + } +} + +// Define a structure where the fields are nameable for comparison. +#[derive(Debug)] +struct Point2 { + x: f64, + y: f64, +} + +// Similarly, implement for Point2 +impl fmt::Display for Point2 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Customize so only `x` and `y` are denoted. + write!(f, "x: {}, y: {}", self.x, self.y) + } +} + +fn main() { + let minmax = MinMax(0, 14); + + println!("Compare structures:"); + println!("Display: {}", minmax); + println!("Debug: {:?}", minmax); + + let big_range = MinMax(-300, 300); + let small_range = MinMax(-3, 3); + + println!("The big range is {big} and the small is {small}", + small = small_range, + big = big_range); + + let point = Point2 { x: 3.3, y: 7.2 }; + + println!("Compare points:"); + println!("Display: {}", point); + println!("Debug: {:?}", point); + + // Error. Both `Debug` and `Display` were implemented but `{:b}` + // requires `fmt::Binary` to be implemented. This will not work. + // println!("What does Point2D look like in binary: {:b}?", point); +} diff --git a/examples/print/print_display/input.md b/examples/print/print_display/input.md new file mode 100644 index 0000000000..8b6aa37feb --- /dev/null +++ b/examples/print/print_display/input.md @@ -0,0 +1,58 @@ +`fmt::Debug` hardly looks compact and clean, so it is often advantageous to +customize the output appearance. This is done by manually implementing +[`fmt::Display`][fmt], which uses the `{}` print marker. Implementing it +looks like this: + +```rust +// Import the `fmt` module to make it available via `use`. +use std::fmt; + +// Define a structure which `fmt::Display` will be implemented for. This is simply +// a structure containing an `i32` bound to the name `Structure`. +struct Structure(i32); + +// In order to use the `{}` marker, the trait `fmt::Display` must be implemented +// manually for the type. +impl fmt::Display for Structure { + // This trait requires `fmt` with this exact signature. + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Print strictly the first element in the structure. `write!` uses + // syntax which is very similar to `println!`. + write!(f, "{}", self.0) + } +} +``` + +`fmt::Display` may be cleaner than `fmt::Debug` but this presents +a problem for the `std` library. How should ambiguous types be displayed? +For example, if the `std` library implemented a single style for all +`Vec`, what style should it be? Either of these two? + +* `Vec`: `/:/etc:/home/username:/bin` (split on `:`) +* `Vec`: `1,2,3` (split on `,`) + +No, because there is no ideal style for all types and the `std` library +doesn't presume to dictate one. `fmt::Display` is not implemented for `Vec` +or for any other generic containers. `fmt::Debug` must then be used for these +generic cases. + +This is not a problem though because for any new *container* type which is +*not* generic,`fmt::Display` can be implemented. + +{display.play} + +So, `fmt::Display` has been implemented but `fmt::Binary` has not, and +therefore cannot be used. `std::fmt` has many such [`trait`s][traits] and +each requires it's own implementation. This is detailed further in +[`std::fmt`][fmt]. + +### See also: +[`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], +[`trait`][traits], and [use][use] + +[derive]: ./trait/derive.html +[fmt]: http://doc.rust-lang.org/std/fmt/ +[macros]: ./macros.html +[structs]: ./structs.html +[traits]: ./trait.html +[use]: ./mod/use.html diff --git a/examples/structure.json b/examples/structure.json index 3766b3e11d..6f3b8b8587 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -1,6 +1,9 @@ [ { "id": "hello", "title": "Hello World", "children": null }, - { "id": "print", "title": "Formatted print", "children": null }, + { "id": "print", "title": "Formatted print", "children": [ + { "id": "print_debug", "title": "Debug", "children": null }, + { "id": "print_display", "title": "Display", "children": null } + ] }, { "id": "literals", "title": "Literals and operators", "children": null }, { "id": "variable_bindings", "title": "Variable Bindings", "children": [ { "id": "mut", "title": "Mutability", "children": null }, From 3c1ea708c0e83236f73d24451bfa6d57e7c6ed9a Mon Sep 17 00:00:00 2001 From: Sanjiv Jha Date: Sat, 21 Mar 2015 04:54:06 +0530 Subject: [PATCH 0182/1122] Fixed rustc-serialize issue +Occuring due to rust-serializer has been locked to 0.3.3 which does not have std::os::prelude::unix support, so it giving missing errors --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7640048751..5a579c5611 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" From 18557a4eb9993b3cf05a65ba12f07d5b2e8717bd Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 21 Mar 2015 22:25:16 -0400 Subject: [PATCH 0183/1122] Fix warnings/errors in process/pipe --- examples/process/pipe/pipe.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index dd833175c2..d96aa4fa7a 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,15 +1,19 @@ -#![feature(io)] +#![feature(core)] -use std::process::Command; +use std::error::Error; use std::io::prelude::*; +use std::process::{Command, Stdio}; static PANGRAM: &'static str = "the quick brown fox jumped over the lazy dog\n"; fn main() { // Spawn the `wc` command - let process = match Command::new("wc").spawn() { - Err(why) => panic!("couldn't spawn wc: {}", why.description()), + let process = match Command::new("wc") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() { + Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)), Ok(process) => process, }; @@ -17,7 +21,7 @@ fn main() { // Write a string to the stdin of `wc` match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { Err(why) => panic!("couldn't write to wc stdin: {}", - why.description()), + Error::description(&why)), Ok(_) => println!("sent pangram to wc"), } @@ -32,7 +36,7 @@ fn main() { let mut s = String::new(); match process.stdout.unwrap().read_to_string(&mut s) { Err(why) => panic!("couldn't read wc stdout: {}", - why.description()), + Error::description(&why)), Ok(_) => print!("wc responded with:\n{}", s), } } From 20bb86e398bdfc0a5b0616566239a34cf6ad472d Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 22 Mar 2015 10:49:09 -0400 Subject: [PATCH 0184/1122] Update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a579c5611..9d01eda680 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] From 265e8f3af68fdbb25744e4198dab70d31707362f Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 22 Mar 2015 10:50:20 -0400 Subject: [PATCH 0185/1122] Fix the build --- examples/file/create/create.rs | 10 ++++++---- examples/file/open/open.rs | 13 ++++++++----- examples/fs/fs.rs | 10 ++++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 85e7a17528..7cbc1ec3ef 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,5 +1,4 @@ -#![feature(old_path)] -#![feature(io)] +#![feature(core)] static LOREM_IPSUM: &'static str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod @@ -10,8 +9,10 @@ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "; +use std::error::Error; use std::io::prelude::*; use std::fs::File; +use std::path::Path; fn main() { let path = Path::new("out/lorem_ipsum.txt"); @@ -21,14 +22,15 @@ fn main() { let mut file = match File::create(&path) { Err(why) => panic!("couldn't create {}: {}", display, - why.description()), + Error::description(&why)), Ok(file) => file, }; // Write the `LOREM_IPSUM` string to `file`, returns `IoResult<()>` match file.write_all(LOREM_IPSUM.as_bytes()) { Err(why) => { - panic!("couldn't write to {}: {}", display, why.description()) + panic!("couldn't write to {}: {}", display, + Error::description(&why)) }, Ok(_) => println!("successfully wrote to {}", display), } diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index 02b433a8b4..5f15ac2c69 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,8 +1,9 @@ -#![feature(old_path)] -#![feature(io)] +#![feature(core)] -use std::io::prelude::*; +use std::error::Error; use std::fs::File; +use std::io::prelude::*; +use std::path::Path; fn main() { // Create a path to the desired file @@ -12,14 +13,16 @@ fn main() { // Open the path in read-only mode, returns `IoResult` let mut file = match File::open(&path) { // The `desc` field of `IoError` is a string that describes the error - Err(why) => panic!("couldn't open {}: {}", display, why.description()), + Err(why) => panic!("couldn't open {}: {}", display, + Error::description(&why)), Ok(file) => file, }; // Read the file contents into a string, returns `IoResult` let mut s = String::new(); match file.read_to_string(&mut s) { - Err(why) => panic!("couldn't read {}: {}", display, why.description()), + Err(why) => panic!("couldn't read {}: {}", display, + Error::description(&why)), Ok(_) => print!("{} contains:\n{}", display, s), } diff --git a/examples/fs/fs.rs b/examples/fs/fs.rs index 1619f15fcc..128b717521 100644 --- a/examples/fs/fs.rs +++ b/examples/fs/fs.rs @@ -1,19 +1,17 @@ -#![feature(io)] -#![feature(old_path)] #![feature(fs_walk)] +use std::fs; +use std::fs::{File, OpenOptions}; use std::io; use std::io::prelude::*; -use std::fs; -use std::fs::File; -use std::fs::OpenOptions; +use std::path::Path; // A simple implementation of `% cat path` fn cat(path: &Path) -> io::Result { let mut f = try!(File::open(path)); let mut s = String::new(); match f.read_to_string(&mut s) { - Ok(o) => Ok(s), + Ok(_) => Ok(s), Err(e) => Err(e), } } From 124549082d14fbacc0e488b943c740b074b38f36 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 25 Mar 2015 18:53:12 -0400 Subject: [PATCH 0186/1122] Update cargo lock --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d01eda680..7d096308ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" From 0e954d3b5244d860f69bf70fa2fac20c948ef0f2 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 25 Mar 2015 19:26:07 -0400 Subject: [PATCH 0187/1122] Fix warnings: dashes to underscores --- .../doc-comment.rs => doc_comment/doc_comment.rs} | 0 .../comment/{doc-comment => doc_comment}/input.md | 2 +- examples/enum/{c-like/c-like.rs => c_like/c_like.rs} | 0 examples/enum/{c-like => c_like}/input.md | 2 +- .../{if-else/if-else.rs => if_else/if_else.rs} | 0 examples/flow_control/{if-else => if_else}/input.md | 2 +- .../alt_key_types.rs} | 0 .../hash/{alt-key-types => alt_key_types}/input.md | 2 +- examples/structure.json | 8 ++++---- examples/test/input.md | 12 ++++++------ examples/test/{unit-test.rs => unit_test.rs} | 0 src/main.rs | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) rename examples/comment/{doc-comment/doc-comment.rs => doc_comment/doc_comment.rs} (100%) rename examples/comment/{doc-comment => doc_comment}/input.md (94%) rename examples/enum/{c-like/c-like.rs => c_like/c_like.rs} (100%) rename examples/enum/{c-like => c_like}/input.md (75%) rename examples/flow_control/{if-else/if-else.rs => if_else/if_else.rs} (100%) rename examples/flow_control/{if-else => if_else}/input.md (94%) rename examples/hash/{alt-key-types/alt-key-types.rs => alt_key_types/alt_key_types.rs} (100%) rename examples/hash/{alt-key-types => alt_key_types}/input.md (98%) rename examples/test/{unit-test.rs => unit_test.rs} (100%) diff --git a/examples/comment/doc-comment/doc-comment.rs b/examples/comment/doc_comment/doc_comment.rs similarity index 100% rename from examples/comment/doc-comment/doc-comment.rs rename to examples/comment/doc_comment/doc_comment.rs diff --git a/examples/comment/doc-comment/input.md b/examples/comment/doc_comment/input.md similarity index 94% rename from examples/comment/doc-comment/input.md rename to examples/comment/doc_comment/input.md index 2e5e1515ac..721deb52fc 100644 --- a/examples/comment/doc-comment/input.md +++ b/examples/comment/doc_comment/input.md @@ -2,7 +2,7 @@ Doc comments are very useful for big projects that require documentation. When running [Rustdoc][1], these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown][2]. -{doc-comment.play} +{doc_comment.play} [1]: https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc.md [2]: https://en.wikipedia.org/wiki/Markdown diff --git a/examples/enum/c-like/c-like.rs b/examples/enum/c_like/c_like.rs similarity index 100% rename from examples/enum/c-like/c-like.rs rename to examples/enum/c_like/c_like.rs diff --git a/examples/enum/c-like/input.md b/examples/enum/c_like/input.md similarity index 75% rename from examples/enum/c-like/input.md rename to examples/enum/c_like/input.md index be1e0cad2b..02bc0a2845 100644 --- a/examples/enum/c-like/input.md +++ b/examples/enum/c_like/input.md @@ -1,3 +1,3 @@ `enum` can also be used as C-like enums. -{c-like.play} +{c_like.play} diff --git a/examples/flow_control/if-else/if-else.rs b/examples/flow_control/if_else/if_else.rs similarity index 100% rename from examples/flow_control/if-else/if-else.rs rename to examples/flow_control/if_else/if_else.rs diff --git a/examples/flow_control/if-else/input.md b/examples/flow_control/if_else/input.md similarity index 94% rename from examples/flow_control/if-else/input.md rename to examples/flow_control/if_else/input.md index f822bd9e8e..1f381bac84 100644 --- a/examples/flow_control/if-else/input.md +++ b/examples/flow_control/if_else/input.md @@ -3,4 +3,4 @@ the boolean condition doesn't need to be surrounded by parentheses, and each condition is followed by a block. `if`-`else` conditionals are expressions, and, all branches must return the same type. -{if-else.play} +{if_else.play} diff --git a/examples/hash/alt-key-types/alt-key-types.rs b/examples/hash/alt_key_types/alt_key_types.rs similarity index 100% rename from examples/hash/alt-key-types/alt-key-types.rs rename to examples/hash/alt_key_types/alt_key_types.rs diff --git a/examples/hash/alt-key-types/input.md b/examples/hash/alt_key_types/input.md similarity index 98% rename from examples/hash/alt-key-types/input.md rename to examples/hash/alt_key_types/input.md index e22ffc4de4..042f01b520 100644 --- a/examples/hash/alt-key-types/input.md +++ b/examples/hash/alt_key_types/input.md @@ -25,7 +25,7 @@ This guide will not cover the specifics of implementing `Hash`. To play around with using a `struct` in `HashMap`, let's try making a very simple user logon system: -{alt-key-types.play} +{alt_key_types.play} [vecmap]: http://doc.rust-lang.org/std/collections/struct.VecMap.html [hash]: http://en.wikipedia.org/wiki/Hash_function diff --git a/examples/structure.json b/examples/structure.json index 6f3b8b8587..a676b8d7eb 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -18,7 +18,7 @@ ] }, { "id": "expression", "title": "Expressions", "children": null }, { "id": "flow_control", "title": "Flow Control", "children": [ - { "id": "if-else", "title": "if/else", "children": null }, + { "id": "if_else", "title": "if/else", "children": null }, { "id": "loop", "title": "loop", "children": [ { "id": "nested", "title": "Nesting and labels", "children": null } ] }, @@ -85,7 +85,7 @@ { "id": "constants", "title": "Global constants", "children": null }, { "id": "methods", "title": "Methods", "children": null }, { "id": "enum", "title": "Enums", "children": [ - { "id": "c-like", "title": "C-like", "children": null } + { "id": "c_like", "title": "C-like", "children": null } ] }, { "id": "panic", "title": "`panic!`", "children": null }, { "id": "option", "title": "`Option`", "children": null }, @@ -120,7 +120,7 @@ { "id": "fs", "title": "Filesystem Operations", "children": null }, { "id": "bench", "title": "Benchmarking", "children": null }, { "id": "comment", "title": "Comments", "children": [ - { "id": "doc-comment", "title": "Doc Comments", "children": null } + { "id": "doc_comment", "title": "Doc Comments", "children": null } ] }, { "id": "ffi", "title": "Foreign Function Interface", "children": null }, { "id": "macros", "title": "macro_rules!", "children": [ @@ -138,7 +138,7 @@ { "id": "unsafe", "title": "Unsafe operations", "children": null }, { "id": "fmt", "title": "Formatting", "children": null }, { "id": "hash", "title": "HashMap", "children": [ - { "id": "alt-key-types", "title": "Alternate/custom key types", "children": null}, + { "id": "alt_key_types", "title": "Alternate/custom key types", "children": null}, { "id": "hashset", "title": "HashSet", "children": null } ] } ] diff --git a/examples/test/input.md b/examples/test/input.md index ecbaa0d715..5c14555397 100644 --- a/examples/test/input.md +++ b/examples/test/input.md @@ -2,7 +2,7 @@ To mark a function as a unit test, place `#[test]` (equivalent to `#[cfg(test)]`) above any function. The function must take no parameters and return nothing. -{unit-test.rs} +{unit_test.rs} If you want the test to fail, just put `#[should_fail]` under `#[test]`. @@ -19,8 +19,8 @@ compiled with `--test`. **note**: programs compiled with `--test` *ignore* information passed to stdout ``` -$ rustc --test unit-test.rs -$ ./unit-test +$ rustc --test unit_test.rs +$ ./unit_test running 1 test test distance_test ... ok @@ -30,7 +30,7 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured If `--test` were not included, then this would happen ``` -$ rustc unit-test.rs -$ ./unit-test +$ rustc unit_test.rs +$ ./unit_test If you see this, the tests were not compiled nor ran! -``` \ No newline at end of file +``` diff --git a/examples/test/unit-test.rs b/examples/test/unit_test.rs similarity index 100% rename from examples/test/unit-test.rs rename to examples/test/unit_test.rs diff --git a/src/main.rs b/src/main.rs index 4e2c85dc6f..9fdefcb830 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ extern crate regex; -extern crate "rustc-serialize" as rustc_serialize; +extern crate rustc_serialize; use example::Example; use std::thread; From 70de0a724b681c182e3771970ac6e6c29b015d4f Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 25 Mar 2015 20:29:32 -0400 Subject: [PATCH 0188/1122] Fix some warnings --- examples/arg/getopts/echo.rs | 6 +++--- examples/file/create/create.rs | 2 -- examples/file/open/open.rs | 2 -- examples/flow_control/loop/nested/nested.rs | 2 ++ examples/hof/hof.rs | 6 +++--- examples/iter/iter.rs | 4 +--- examples/path/path.rs | 1 - examples/process/pipe/pipe.rs | 2 -- examples/timers/timers.rs | 8 +++----- 9 files changed, 12 insertions(+), 21 deletions(-) diff --git a/examples/arg/getopts/echo.rs b/examples/arg/getopts/echo.rs index cd565ac404..c004d94f34 100644 --- a/examples/arg/getopts/echo.rs +++ b/examples/arg/getopts/echo.rs @@ -1,4 +1,3 @@ -#![feature(old_io)] #![feature(rustc_private)] #![feature(collections)] #![feature(exit_status)] @@ -6,7 +5,8 @@ extern crate getopts; use std::env; -use std::old_io::stdio; +use std::io; +use std::io::Write; static VERSION: &'static str = "1.0.0"; @@ -64,6 +64,6 @@ fn main() { if !matches.opt_present("n") { println!("") } else { - stdio::flush(); + let _ = io::stdout().flush(); } } diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 7cbc1ec3ef..0ffb9d8cca 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -1,5 +1,3 @@ -#![feature(core)] - static LOREM_IPSUM: &'static str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index 5f15ac2c69..bce6763936 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -1,5 +1,3 @@ -#![feature(core)] - use std::error::Error; use std::fs::File; use std::io::prelude::*; diff --git a/examples/flow_control/loop/nested/nested.rs b/examples/flow_control/loop/nested/nested.rs index 786fabab0e..32f1226d09 100644 --- a/examples/flow_control/loop/nested/nested.rs +++ b/examples/flow_control/loop/nested/nested.rs @@ -1,3 +1,5 @@ +#![allow(unreachable_code)] + fn main() { 'outer: loop { println!("Entered the outer loop"); diff --git a/examples/hof/hof.rs b/examples/hof/hof.rs index 7b40a406e1..563d7d35ed 100644 --- a/examples/hof/hof.rs +++ b/examples/hof/hof.rs @@ -1,8 +1,8 @@ +#![feature(step_by)] #![feature(core)] // The `AdditiveIterator` trait adds the `sum` method to iterators use std::iter::AdditiveIterator; -use std::iter; fn main() { println!("Find the sum of all the squared odd numbers under 1000"); @@ -12,7 +12,7 @@ fn main() { // Declare accumulator variable let mut acc = 0; // Iterate: 0, 1, 2, ... to infinity - for n in iter::count(0u32, 1) { + for n in (0u32..).step_by(1) { // Square the number let n_squared = n * n; @@ -29,7 +29,7 @@ fn main() { // Functional approach let sum_of_squared_odd_numbers = // All natural numbers - iter::count(0u32, 1). + (0u32..).step_by(1). // Squared map(|n| n * n). // Below upper limit diff --git a/examples/iter/iter.rs b/examples/iter/iter.rs index 076ddd66ef..e260b22377 100644 --- a/examples/iter/iter.rs +++ b/examples/iter/iter.rs @@ -1,5 +1,3 @@ -#![feature(core)] - struct Fibonacci { curr: u32, next: u32, @@ -61,7 +59,7 @@ fn main() { let array = [1u32, 3, 3, 7]; // The 'iter' method produces an 'Iterator' over an array/slice - println!("Iterate the following array {:?}", array.as_slice()); + println!("Iterate the following array {:?}", &array); for i in array.iter() { println!("> {}", i); } diff --git a/examples/path/path.rs b/examples/path/path.rs index 92100175c2..73c5226053 100644 --- a/examples/path/path.rs +++ b/examples/path/path.rs @@ -1,4 +1,3 @@ -#![feature(path)] #![feature(path_ext)] use std::path::Path; diff --git a/examples/process/pipe/pipe.rs b/examples/process/pipe/pipe.rs index d96aa4fa7a..29fdb71ce0 100644 --- a/examples/process/pipe/pipe.rs +++ b/examples/process/pipe/pipe.rs @@ -1,5 +1,3 @@ -#![feature(core)] - use std::error::Error; use std::io::prelude::*; use std::process::{Command, Stdio}; diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 738377ddcd..7a29178253 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -1,11 +1,9 @@ -#![feature(core)] #![feature(old_io)] #![feature(std_misc)] +#![feature(step_by)] -use std::old_io::Timer; -use std::old_io::timer; +use std::old_io::{timer, Timer}; use std::time::duration::Duration; -use std::iter; use std::sync::mpsc; fn main() { @@ -36,7 +34,7 @@ fn main() { let metronome: mpsc::Receiver<()> = timer.periodic(interval); println!("Countdown"); - for i in iter::range_step(5i32, 0, -1) { + for i in (5i32..0).step_by(-1) { // This loop will run once every second let _ = metronome.recv(); From 2c93011bd7b7197b7e185339af65fdf59878f76c Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 28 Mar 2015 16:25:47 -0400 Subject: [PATCH 0189/1122] Fix warning. Add a link. --- examples/type/alias/alias.rs | 2 ++ examples/type/alias/input.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/type/alias/alias.rs b/examples/type/alias/alias.rs index 74e6f52938..42fa99b080 100644 --- a/examples/type/alias/alias.rs +++ b/examples/type/alias/alias.rs @@ -7,6 +7,8 @@ type Inch = u64; type u64_t = u64; // TODO ^ Try removing the attribute +// Use an attribute to silence warnings +#[allow(trivial_numeric_casts)] fn main() { // `NanoSecond` = `Inch` = `u64_t` = `u64`. let nanoseconds: NanoSecond = 5 as u64_t; diff --git a/examples/type/alias/input.md b/examples/type/alias/input.md index 4cbacb952a..58b2e56c73 100644 --- a/examples/type/alias/input.md +++ b/examples/type/alias/input.md @@ -7,3 +7,5 @@ exception to this rule are the primitive types: `usize`, `f32`, etc. The main use of aliases is to reduce typing; for example the `IoResult` type is an alias for the `Result` type. +### See also: +[attributes](./attribute.html) From b2f1f5000341e1cb05587670aac18ab31e3636da Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 29 Mar 2015 15:19:25 -0400 Subject: [PATCH 0190/1122] Update cargo lock --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d096308ee..803b056680 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" From ae2926af0bb3c4fcab465b4280b83a3ad82bcd27 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 29 Mar 2015 15:43:32 -0400 Subject: [PATCH 0191/1122] Fix build errors --- examples/arg/matching/match_args.rs | 2 ++ src/example.rs | 8 ++++---- src/main.rs | 4 +--- src/markdown.rs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/arg/matching/match_args.rs b/examples/arg/matching/match_args.rs index 3bf9e9e1a2..6d7abcf458 100644 --- a/examples/arg/matching/match_args.rs +++ b/examples/arg/matching/match_args.rs @@ -1,3 +1,5 @@ +#![feature(slice_patterns)] + use std::env; fn increase(number: i32) { diff --git a/src/example.rs b/src/example.rs index ee31e96393..6697a26e33 100644 --- a/src/example.rs +++ b/src/example.rs @@ -33,7 +33,7 @@ impl Example { } } - pub fn count(&self) -> uint { + pub fn count(&self) -> usize { match self.children { None => 1, Some(ref children) => 1 + children.iter().map(|c| c.count()).sum(), @@ -41,9 +41,9 @@ impl Example { } pub fn process(&self, - number: Vec, - tx: mpsc::Sender<(Vec, String)>, - indent: uint, + number: Vec, + tx: mpsc::Sender<(Vec, String)>, + indent: usize, prefix: String) { let id = &self.id; diff --git a/src/main.rs b/src/main.rs index 9fdefcb830..d3d0826c3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,9 @@ #![feature(core)] #![deny(warnings)] -#![feature(int_uint)] #![feature(plugin)] extern crate regex; - extern crate rustc_serialize; use example::Example; @@ -36,7 +34,7 @@ fn main() { let mut entries = (0..nexamples).map(|_| { rx.recv().unwrap() - }).collect::, String)>>(); + }).collect::, String)>>(); entries.sort_by(|&(ref i, _), &(ref j, _)| i.cmp(j)); diff --git a/src/markdown.rs b/src/markdown.rs index 54ad864267..effaa63d4b 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -14,7 +14,7 @@ pub struct Markdown<'a, 'b> { } impl<'a, 'b> Markdown<'a, 'b> { - pub fn process(number: &[uint], id: &'a str, title: &str, prefix: &'b str) + pub fn process(number: &[usize], id: &'a str, title: &str, prefix: &'b str) -> Result<(), String> { let mut mkd = try!(Markdown::new(number, id, title, prefix)); @@ -27,7 +27,7 @@ impl<'a, 'b> Markdown<'a, 'b> { Ok(()) } - fn new(number: &[uint], id: &'a str, title: &str, prefix: &'b str) + fn new(number: &[usize], id: &'a str, title: &str, prefix: &'b str) -> Result, String> { let path_str = &format!("examples/{}/{}/input.md", prefix, id); From 16737c6cb7a421272ec51d9779cb76558a640de8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 29 Mar 2015 19:48:49 -0400 Subject: [PATCH 0192/1122] Use downloaded rust rules, not old ones --- .gitignore | 1 + node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js | 1 - setup-stage.sh | 5 +++-- 3 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js diff --git a/.gitignore b/.gitignore index 831b59a7bb..6fde780044 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ bin/* stage/* node_modules/* !node_modules/gitbook-plugin-rust-playpen +node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js node_modules/gitbook-plugin-rust-playpen/book/ace target diff --git a/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js b/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js deleted file mode 100644 index f43a904c74..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js +++ /dev/null @@ -1 +0,0 @@ -ace.define("ace/mode/rust",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/rust_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./rust_highlight_rules").RustHighlightRules,u=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=o,this.foldingRules=new u};r.inherits(a,i),function(){this.lineCommentStart="/\\*",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/rust"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/rust_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"variable.other.source.rust",regex:"'[a-zA-Z_][a-zA-Z0-9_]*[^\\']"},{token:"string.quoted.single.source.rust",regex:"'",push:[{token:"string.quoted.single.source.rust",regex:"'",next:"pop"},{include:"#rust_escaped_character"},{defaultToken:"string.quoted.single.source.rust"}]},{token:"string.quoted.double.source.rust",regex:'"',push:[{token:"string.quoted.double.source.rust",regex:'"',next:"pop"},{include:"#rust_escaped_character"},{defaultToken:"string.quoted.double.source.rust"}]},{token:["keyword.source.rust","meta.function.source.rust","entity.name.function.source.rust","meta.function.source.rust"],regex:"\\b(fn)(\\s+)([a-zA-Z_][a-zA-Z0-9_][\\w\\:,+ \\'<>]*)(\\s*\\()"},{token:"support.constant",regex:"\\b[a-zA-Z_][\\w\\d]*::"},{token:"keyword.source.rust",regex:"\\b(?:as|assert|break|claim|const|copy|Copy|do|drop|else|extern|fail|for|if|impl|in|let|log|loop|match|mod|module|move|mut|Owned|priv|pub|pure|ref|return|unchecked|unsafe|use|while|mod|Send|static|trait|class|struct|enum|type)\\b"},{token:"storage.type.source.rust",regex:"\\b(?:Self|m32|m64|m128|f80|f16|f128|int|uint|float|char|bool|u8|u16|u32|u64|f32|f64|i8|i16|i32|i64|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b"},{token:"variable.language.source.rust",regex:"\\bself\\b"},{token:"keyword.operator",regex:"!|\\$|\\*|\\-\\-|\\-|\\+\\+|\\+|-->|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|/=|%=|\\+=|\\-=|&=|\\^=|,|;"},{token:"constant.language.source.rust",regex:"\\b(?:true|false|Some|None|Left|Right|Ok|Err)\\b"},{token:"support.constant.source.rust",regex:"\\b(?:EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\\b"},{token:"meta.preprocessor.source.rust",regex:"\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b"},{token:"constant.numeric.integer.source.rust",regex:"\\b(?:[0-9][0-9_]*|[0-9][0-9_]*(?:u|u8|u16|u32|u64)|[0-9][0-9_]*(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.hex.source.rust",regex:"\\b(?:0x[a-fA-F0-9_]+|0x[a-fA-F0-9_]+(?:u|u8|u16|u32|u64)|0x[a-fA-F0-9_]+(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.binary.source.rust",regex:"\\b(?:0b[01_]+|0b[01_]+(?:u|u8|u16|u32|u64)|0b[01_]+(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.float.source.rust",regex:"[0-9][0-9_]*(?:f32|f64|f)|[0-9][0-9_]*[eE][+-]=[0-9_]+|[0-9][0-9_]*[eE][+-]=[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+|[0-9][0-9_]*\\.[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+(?:f32|f64|f)"},{token:"comment.line.documentation.source.rust",regex:"//!.*$",push_:[{token:"comment.line.documentation.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.documentation.source.rust"}]},{token:"comment.line.double-dash.source.rust",regex:"//.*$",push_:[{token:"comment.line.double-dash.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.source.rust"}]},{token:"comment.block.source.rust",regex:"/\\*",push:[{token:"comment.block.source.rust",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.source.rust"}]}],"#rust_escaped_character":[{token:"constant.character.escape.source.rust",regex:"\\\\(?:x[\\da-fA-F]{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)"}]},this.normalizeRules()};s.metaData={fileTypes:["rs","rc"],foldingStartMarker:"^.*\\bfn\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$",foldingStopMarker:"^\\s*\\}",name:"Rust",scopeName:"source.rust"},r.inherits(s,i),t.RustHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}) \ No newline at end of file diff --git a/setup-stage.sh b/setup-stage.sh index 484ae186a9..eca4b5fed2 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -1,11 +1,12 @@ #!/bin/bash ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min-noconflict' -ace_local_folder='node_modules/gitbook-plugin-rust-playpen/book/ace' +ace_playpen_local='node_modules/gitbook-plugin-rust-playpen' mkdir -p bin mkdir -p stage/node_modules -svn checkout ${ace_repository} ${ace_local_folder} +svn checkout ${ace_repository} ${ace_playpen_local}'/book/ace' +cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' ln -sf ../book.json stage ln -sf ../examples/README.md stage From 38c9ed15c3db3adc4b1f102e6925769237354c7a Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 30 Mar 2015 18:39:10 -0400 Subject: [PATCH 0193/1122] Clarify the purpose of match binding --- examples/flow_control/match/binding/binding.rs | 16 +++++++++++----- examples/flow_control/match/binding/input.md | 9 ++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/flow_control/match/binding/binding.rs b/examples/flow_control/match/binding/binding.rs index d7dcb86986..09a81d64d6 100644 --- a/examples/flow_control/match/binding/binding.rs +++ b/examples/flow_control/match/binding/binding.rs @@ -1,10 +1,16 @@ -fn main() { - let age = 3; - // TODO ^ Try different values for `age` +// A function `age` which returns a `u32`. +fn age() -> u32 { + 15 +} +fn main() { println!("Tell me type of person you are"); - match age { - // Bind to `n` for the sequence of 1 through 12. + + match age() { + 0 => println!("I'm not born yet I guess"), + // Could `match` 1 ... 12 directly but then what age + // would the child be? Instead, bind to `n` for the + // sequence of 1 .. 12. Now the age can be reported. n @ 1 ... 12 => println!("I'm a child of age {:?}", n), n @ 13 ... 19 => println!("I'm a teen of age {:?}", n), // Nothing bound. Return the result. diff --git a/examples/flow_control/match/binding/input.md b/examples/flow_control/match/binding/input.md index 28b9839ffa..005962df40 100644 --- a/examples/flow_control/match/binding/input.md +++ b/examples/flow_control/match/binding/input.md @@ -1,3 +1,10 @@ -Rust supports binding variables via a `match`: +Indirectly accessing a variable makes it impossible to branch and use that +variable without re-binding. `match` provides the `@` sigil for exactly +this purpose: {binding.play} + +### See also: +[functions][functions] + +[functions]: /fn.html From 642187ee9c00659875d5d4613c7d937006670250 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 2 Apr 2015 13:11:23 -0400 Subject: [PATCH 0194/1122] Add the cfg! macro to cfg --- examples/attribute/cfg/cfg.rs | 7 +++++++ examples/attribute/cfg/input.md | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/examples/attribute/cfg/cfg.rs b/examples/attribute/cfg/cfg.rs index 95dd647bfa..60020174e5 100644 --- a/examples/attribute/cfg/cfg.rs +++ b/examples/attribute/cfg/cfg.rs @@ -12,4 +12,11 @@ fn are_you_on_linux() { fn main() { are_you_on_linux(); + + println!("Are you sure?"); + if cfg!(target_os = "linux") { + println!("Yes. It's definitely linux!"); + } else { + println!("Yes. It's definitely *not* linux!"); + } } diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md index 2a255e65fd..0bce172d22 100644 --- a/examples/attribute/cfg/input.md +++ b/examples/attribute/cfg/input.md @@ -1,7 +1,16 @@ -The `cfg` attribute can be use to achieve conditional compilation. +Conditional compilation is possible through two different operators: + +* the `cfg` attribute: `#[cfg(...)]` in attribute position +* the `cfg!` macro: `cfg!(...)` in boolean expressions + +Both utilize identical syntax. {cfg.play} -See [the -Reference](http://doc.rust-lang.org/reference.html#conditional-compilation) for -more details. +### See also: + +[the reference][ref], [`cfg!`][cfg], and [macros][macros]. + +[cfg]: http://doc.rust-lang.org/std/macro.cfg!.html +[macros]: /macros.html +[ref]: http://doc.rust-lang.org/reference.html#conditional-compilation From ea9b61fe241ce0e3ec2108a5ca5821e490c2d104 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 2 Apr 2015 13:49:28 -0400 Subject: [PATCH 0195/1122] Update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 803b056680..dfdb8ff9ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" From 70ba2c8bf1171e8b5cff59c6bc4a6881203b2a9b Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 2 Apr 2015 14:41:13 -0400 Subject: [PATCH 0196/1122] Fix float warnings --- examples/fmt/show.rs | 2 -- examples/methods/methods.rs | 3 --- examples/result/result.rs | 2 -- examples/result/try/try.rs | 3 --- 4 files changed, 10 deletions(-) diff --git a/examples/fmt/show.rs b/examples/fmt/show.rs index 6b06cab457..4765402bf6 100644 --- a/examples/fmt/show.rs +++ b/examples/fmt/show.rs @@ -1,6 +1,4 @@ use std::fmt::{self, Formatter, Display}; -// For .abs() -use std::num::Float; struct City { name: &'static str, diff --git a/examples/methods/methods.rs b/examples/methods/methods.rs index f33df1b5ff..599ee4c469 100644 --- a/examples/methods/methods.rs +++ b/examples/methods/methods.rs @@ -1,6 +1,3 @@ -use std::num::Float; -// To be able to use .abs(), you must include this - struct Point { x: f64, y: f64, diff --git a/examples/result/result.rs b/examples/result/result.rs index 8f8821cf94..a0e8c6dfcc 100644 --- a/examples/result/result.rs +++ b/examples/result/result.rs @@ -1,6 +1,4 @@ mod checked { - // For .ln() and .sqrt() - use std::num::Float; // Mathematical "errors" we want to catch #[derive(Debug)] pub enum MathError { diff --git a/examples/result/try/try.rs b/examples/result/try/try.rs index 132cbeb100..acca8e37ad 100644 --- a/examples/result/try/try.rs +++ b/examples/result/try/try.rs @@ -1,7 +1,4 @@ mod checked { - // For .sqrt() and .ln() - use std::num::Float; - #[derive(Debug)] enum MathError { DivisionByZero, From 3c68374e854a659d2842dc6ef935c8b01e80bcbe Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 2 Apr 2015 14:54:52 -0400 Subject: [PATCH 0197/1122] Add a blank line after `See also:` --- examples/flow_control/if_let/input.md | 1 + .../flow_control/match/destructuring/destructure_enum/input.md | 1 + .../match/destructuring/destructure_references/input.md | 1 + .../match/destructuring/destructure_structures/input.md | 1 + .../flow_control/match/destructuring/destructure_tuple/input.md | 1 + examples/flow_control/match/guard/input.md | 1 + examples/flow_control/match/struct/input.md | 1 + examples/flow_control/while_let/input.md | 1 + examples/generics/impl/input.md | 1 + examples/generics/phantom/input.md | 1 + examples/generics/phantom/units/input.md | 1 + examples/print/input.md | 1 + examples/print/print_debug/input.md | 1 + examples/print/print_display/input.md | 1 + 14 files changed, 14 insertions(+) diff --git a/examples/flow_control/if_let/input.md b/examples/flow_control/if_let/input.md index c17fc3ad6b..3e793edb7e 100644 --- a/examples/flow_control/if_let/input.md +++ b/examples/flow_control/if_let/input.md @@ -23,6 +23,7 @@ failure options to be specified: {if_let.play} ### See also: + [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] [enum]: /enum.html diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index 14e9407e20..83658513f6 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -3,6 +3,7 @@ An `enum` is destructured similarly: {enum.play} ### See also: + [`#[allow(...)]`][allow], [`enum`][enum], and [`#[derive(...)]`][derive] [enum]: /enum.html diff --git a/examples/flow_control/match/destructuring/destructure_references/input.md b/examples/flow_control/match/destructuring/destructure_references/input.md index a74ba8dbfb..0fabde2d6a 100644 --- a/examples/flow_control/match/destructuring/destructure_references/input.md +++ b/examples/flow_control/match/destructuring/destructure_references/input.md @@ -4,6 +4,7 @@ References and mutable references can be retrieved via {ref.play} ### See also: + [Borrowing (`&`)][borrow] [borrow]: /borrow.html diff --git a/examples/flow_control/match/destructuring/destructure_structures/input.md b/examples/flow_control/match/destructuring/destructure_structures/input.md index 8025cb675d..d393ee3190 100644 --- a/examples/flow_control/match/destructuring/destructure_structures/input.md +++ b/examples/flow_control/match/destructuring/destructure_structures/input.md @@ -3,4 +3,5 @@ Similarly, a `struct` can be destructured as shown: {struct.play} ### See also: + [Structs](/structs.html), [The ref pattern](/borrow/ref.html) diff --git a/examples/flow_control/match/destructuring/destructure_tuple/input.md b/examples/flow_control/match/destructuring/destructure_tuple/input.md index c3943b7a5e..2394fe6bb5 100644 --- a/examples/flow_control/match/destructuring/destructure_tuple/input.md +++ b/examples/flow_control/match/destructuring/destructure_tuple/input.md @@ -3,4 +3,5 @@ Tuples can be destructured in a `match` as follows: {tuples.play} ### See also: + [Tuples](/tuples.html) diff --git a/examples/flow_control/match/guard/input.md b/examples/flow_control/match/guard/input.md index 3bf630622d..a9b0987a78 100644 --- a/examples/flow_control/match/guard/input.md +++ b/examples/flow_control/match/guard/input.md @@ -3,4 +3,5 @@ A `match` *guard* can be added to filter the arm. {guard.play} ### See also: + [Tuples](/tuples.html) diff --git a/examples/flow_control/match/struct/input.md b/examples/flow_control/match/struct/input.md index 9c405ce7a7..e3c274dae3 100644 --- a/examples/flow_control/match/struct/input.md +++ b/examples/flow_control/match/struct/input.md @@ -3,4 +3,5 @@ A `struct` can be destructured with pattern matching. {struct.play} ### See also: + [Structs](/structs.html) diff --git a/examples/flow_control/while_let/input.md b/examples/flow_control/while_let/input.md index 89eccb7b64..925f888f53 100644 --- a/examples/flow_control/while_let/input.md +++ b/examples/flow_control/while_let/input.md @@ -31,6 +31,7 @@ loop { {while_let.play} ### See also: + [`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] [enum]: /enum.html diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index a0af35e9ed..0544b6650e 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -16,6 +16,7 @@ impl GenericTup {} {impl.play} ###See also: + [impl](http://rustbyexample.com/methods.html), [struct](http://rustbyexample.com/structs.html), and [functions returning references](http://rustbyexample.com/lifetime/fn.html), diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 62af7fa4dc..8011bdee07 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -6,6 +6,7 @@ at compile time; they have no run-time behavior. {phantom.play} ###See also: + [Derive](http://rustbyexample.com/trait/derive.html), [struct](http://rustbyexample.com/structs.html), and [TupleStructs](http://rustbyexample.com/structs.html) diff --git a/examples/generics/phantom/units/input.md b/examples/generics/phantom/units/input.md index f445d51557..a8d68263e1 100644 --- a/examples/generics/phantom/units/input.md +++ b/examples/generics/phantom/units/input.md @@ -3,6 +3,7 @@ A useful method of unit conversions: {units.play} ###See also: + [Borrowing (`&`)](http://rustbyexample.com/borrow.html), [Bounds (`X: Y`)](http://rustbyexample.com/bounds.html), [enum](http://rustbyexample.com/enum.html), diff --git a/examples/print/input.md b/examples/print/input.md index e235cbde12..3357f4a22a 100644 --- a/examples/print/input.md +++ b/examples/print/input.md @@ -21,6 +21,7 @@ Here, `fmt::Display` was used because the std library provides implementations for these types. To print text for custom types, more steps are required. ### See also: + [`std::fmt`][fmt], [macros][macros], [`struct`][structs], and [`trait`s][traits] diff --git a/examples/print/print_debug/input.md b/examples/print/print_debug/input.md index a2abde3fb1..5cc3218b4a 100644 --- a/examples/print/print_debug/input.md +++ b/examples/print/print_debug/input.md @@ -26,6 +26,7 @@ So `fmt::Debug` definitely makes this printable but sacrifices some elegance. Manually implementing `fmt::Display` will fix that. ### See also: + [attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], and [`struct`][structs] diff --git a/examples/print/print_display/input.md b/examples/print/print_display/input.md index 8b6aa37feb..37529944ca 100644 --- a/examples/print/print_display/input.md +++ b/examples/print/print_display/input.md @@ -47,6 +47,7 @@ each requires it's own implementation. This is detailed further in [`std::fmt`][fmt]. ### See also: + [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] From ab15d8d97cfcdf783dac4c58fd7fde197c1f285d Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 2 Apr 2015 15:08:32 -0400 Subject: [PATCH 0198/1122] Rewrite test --- examples/test/fail.rs | 5 ----- examples/test/input.md | 40 +++++++++++++++++++------------------- examples/test/unit_test.rs | 37 ++++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 39 deletions(-) delete mode 100644 examples/test/fail.rs diff --git a/examples/test/fail.rs b/examples/test/fail.rs deleted file mode 100644 index 15f4c85e2d..0000000000 --- a/examples/test/fail.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[test] -#[should_panic] -fn failing_test() { - assert!(1i32 == 2i32); -} diff --git a/examples/test/input.md b/examples/test/input.md index 5c14555397..556fb18d80 100644 --- a/examples/test/input.md +++ b/examples/test/input.md @@ -1,30 +1,22 @@ -To mark a function as a unit test, place `#[test]` (equivalent -to `#[cfg(test)]`) above any function. The function must take -no parameters and return nothing. +Functions can be tested by using these [attributes][attributes]: -{unit_test.rs} - -If you want the test to fail, just put `#[should_fail]` under `#[test]`. - -{fail.rs} +* `#[test]` marks a function as a unit test. The function must take zero +parameters and return nothing. +* `#[should_panic]` marks a function as a panicking test. -To run unit tests, add either the `--test` or `--cfg test` flag to the -command. When using either flag, you do not need a `main()` function -as the executable will only include and run the functions flagged with -`#[test]` or `#[cfg(test)]`. If you don't pass the `--test` flag, `rustc` will -ignore any functions flagged with `#[test]`. That means calling any function -flagged with `#[test]` will result in `rustc: unresolved name` if it is not -compiled with `--test`. +{unit_test.rs} -**note**: programs compiled with `--test` *ignore* information passed to stdout +Tests can be run with `cargo test` or `rustc --test`. ``` $ rustc --test unit_test.rs -$ ./unit_test -running 1 test -test distance_test ... ok +$ ./unit_test -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured +running 2 tests +test test::distance_test ... ok +test test::failing_test ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured ``` If `--test` were not included, then this would happen @@ -34,3 +26,11 @@ $ rustc unit_test.rs $ ./unit_test If you see this, the tests were not compiled nor ran! ``` + +### See also: + +[attributes][attributes], [conditional compilation][cfg], and [`mod`][mod]. + +[attributes]: ./attribute.html +[cfg]: ./attribute/cfg.html +[mod]: ./mod.html diff --git a/examples/test/unit_test.rs b/examples/test/unit_test.rs index 535ef88bcd..9b470faf37 100644 --- a/examples/test/unit_test.rs +++ b/examples/test/unit_test.rs @@ -1,19 +1,28 @@ -// For .powi() -use std::num::Float; - - -fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { - ( - (b.0.powi(2) - a.0.powi(2)) + - (b.1.powi(2) - a.1.powi(2)) - ).sqrt() -} - +// Conditionally compile `main` only when the test-suite is *not* being run. +#[cfg(not(test))] fn main() { println!("If you see this, the tests were not compiled nor ran!"); } -#[test] -fn distance_test() { - assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt()); +// Conditionally compile the module `test` only when the test-suite is run. +#[cfg(test)] +mod test { + // A helper function `distance_test` will need. + fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { + ( + (b.0.powi(2) - a.0.powi(2)) + + (b.1.powi(2) - a.1.powi(2)) + ).sqrt() + } + + #[test] + fn distance_test() { + assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt()); + } + + #[test] + #[should_panic] + fn failing_test() { + assert!(1i32 == 2i32); + } } From 8c307cc69b60a708b166b102ba0de5fc5a9aafc7 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 3 Apr 2015 12:00:16 -0400 Subject: [PATCH 0199/1122] Update lock --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfdb8ff9ee..a40f671045 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" From 00ca0fd94c5eb83eafdec8a32b9ec62160a9c03b Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Fri, 3 Apr 2015 13:11:47 -0600 Subject: [PATCH 0200/1122] Fix the sentence in the comment - was to want --- examples/print/print_debug/debug.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/print/print_debug/debug.rs b/examples/print/print_debug/debug.rs index 552aa346a9..adcf278214 100644 --- a/examples/print/print_debug/debug.rs +++ b/examples/print/print_debug/debug.rs @@ -20,6 +20,6 @@ fn main() { println!("Now {:?} will print!", Structure(3)); // The problem with `derive` is there is no control over how - // the results look. What if I was this to just show a `7`? + // the results look. What if I want this to just show a `7`? println!("Now {:?} will print!", Deep(Structure(7))); } From bca0dcc166680181f4dc646cf6a44119ab688fa8 Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Sun, 5 Apr 2015 00:09:20 -0400 Subject: [PATCH 0201/1122] type/cast: added detailed integral type casting rules --- examples/type/cast/cast.rs | 32 ++++++++++++++++++++++++++++++++ examples/type/cast/input.md | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/examples/type/cast/cast.rs b/examples/type/cast/cast.rs index 845506bf2f..87a344afb5 100644 --- a/examples/type/cast/cast.rs +++ b/examples/type/cast/cast.rs @@ -10,4 +10,36 @@ fn main() { let character = integer as char; println!("Casting: {} -> {} -> {}", decimal, integer, character); + + // when casting any value to an unsigned type, T, + // std::T::MAX + 1 is added or subtracted until the value + // fits into the new type + + // 1000 already fits in a u16 + println!("1000 as a u16 is: {}", 1000 as u16); + + // 1000 - 256 - 256 = 232 + println!("1000 as a u8 is : {}", 1000 as u8); + // -1 + 256 = 255 + println!(" -1 as a u8 is : {}", (-1i8) as u8); + + // For positive numbers, this is the same as the modulus + println!("1000 mod 256 is : {}", 1000 % 256); + + // When casting to a signed type, the result is the same as + // first casting to the corresponding unsigned type then + // taking the two's complement. + + // Unless it already fits, of course. + println!(" 128 as a i16 is: {}", 128 as i16); + // 128 as u8 -> 128, whose two's complement in eight bits is: + println!(" 128 as a i8 is : {}", 128 as i8); + + // repeating the example above + // 1000 as u8 -> 232 + println!("1000 as a i8 is : {}", 1000 as i8); + // and the two's complement of 232 is -24 + println!(" 232 as a i8 is : {}", 232 as i8); + + } diff --git a/examples/type/cast/input.md b/examples/type/cast/input.md index 98e73bd3ae..658dd9cce9 100644 --- a/examples/type/cast/input.md +++ b/examples/type/cast/input.md @@ -1,4 +1,8 @@ Rust provides no implicit type conversion (coercion) between primitive types. But, explicit type conversion (casting) can be performed using the `as` keyword. +Rules for converting between integral types follow C conventions generally, +except in cases where C has undefined behavior. The behavior of all casts +between integral types is well defined in Rust. + {cast.play} From 69c92217e76f9de5136b959dad9b35d4a2403968 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 5 Apr 2015 14:46:23 -0400 Subject: [PATCH 0202/1122] Add clone to copy --- examples/borrow/mut/mut.rs | 2 +- examples/borrow/ref/ref.rs | 2 +- examples/bounds/bounds.rs | 2 +- examples/box/box.rs | 2 +- examples/clone/clone.rs | 4 ++-- examples/ffi/ffi.rs | 2 +- examples/ffi/safe.rs | 2 +- examples/generics/phantom/units/units.rs | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/borrow/mut/mut.rs b/examples/borrow/mut/mut.rs index e96eb52daa..b126b572fa 100644 --- a/examples/borrow/mut/mut.rs +++ b/examples/borrow/mut/mut.rs @@ -1,5 +1,5 @@ #[allow(dead_code)] -#[derive(Copy)] +#[derive(Clone, Copy)] struct Book { // `&'static str` is a reference to a string allocated in read only memory author: &'static str, diff --git a/examples/borrow/ref/ref.rs b/examples/borrow/ref/ref.rs index 6973d6bd42..810a15c22e 100644 --- a/examples/borrow/ref/ref.rs +++ b/examples/borrow/ref/ref.rs @@ -1,4 +1,4 @@ -#[derive(Copy)] +#[derive(Clone, Copy)] struct Point { x: i32, y: i32 } fn main() { diff --git a/examples/bounds/bounds.rs b/examples/bounds/bounds.rs index 81c95920c7..2522cd3b9a 100644 --- a/examples/bounds/bounds.rs +++ b/examples/bounds/bounds.rs @@ -1,6 +1,6 @@ use std::ops::{Add, Sub, Mul}; -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] struct Vec2 { x: T, y: T, diff --git a/examples/box/box.rs b/examples/box/box.rs index 18da715e15..eb81ba0639 100644 --- a/examples/box/box.rs +++ b/examples/box/box.rs @@ -1,7 +1,7 @@ use std::mem; #[allow(dead_code)] -#[derive(Copy)] +#[derive(Clone, Copy)] struct Point { x: f64, y: f64, diff --git a/examples/clone/clone.rs b/examples/clone/clone.rs index e5d026abef..4a41bc2875 100644 --- a/examples/clone/clone.rs +++ b/examples/clone/clone.rs @@ -1,9 +1,9 @@ // A unit struct without resources -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] struct Nil; // A tuple struct with resources that implements the `Clone` trait -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] struct Pair(Box, Box); fn main() { diff --git a/examples/ffi/ffi.rs b/examples/ffi/ffi.rs index 8adfb6e12e..f96f7a0d54 100644 --- a/examples/ffi/ffi.rs +++ b/examples/ffi/ffi.rs @@ -22,7 +22,7 @@ fn main() { // Minimal implementation of single precision complex numbers #[repr(C)] -#[derive(Copy)] +#[derive(Clone, Copy)] struct Complex { re: f32, im: f32, diff --git a/examples/ffi/safe.rs b/examples/ffi/safe.rs index 4fd258634c..522f6e04de 100644 --- a/examples/ffi/safe.rs +++ b/examples/ffi/safe.rs @@ -19,7 +19,7 @@ fn main() { // Minimal implementation of single precision complex numbers #[repr(C)] -#[derive(Copy)] +#[derive(Clone, Copy)] struct Complex { re: f32, im: f32, diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index df2d1a91f1..8f7ad7cbea 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -2,13 +2,13 @@ use std::ops::Add; use std::marker::PhantomData; /// Null enumerations to define unit types -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] struct Inch; -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] struct Mm; /// Length is phantom type with hidden parameter `Unit` -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] struct Length(T,PhantomData); /// impl X for Y {} means "implement the trait `X` for the Type `Y`" @@ -30,7 +30,7 @@ struct Length(T,PhantomData); /// `type Output = Length` means that this impl gives back a /// `Length`, so that /// `Length + Length = Length` -impl + Copy> Add> +impl + Clone + Copy> Add> for Length { type Output = Length; From ddb1821324e5fa9732b8ea26d018c6c97e4b67b0 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 5 Apr 2015 14:46:46 -0400 Subject: [PATCH 0203/1122] Update travis to nightly --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index de53f705b1..3d87af3af6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: true install: - - curl -L https://static.rust-lang.org/rustup.sh | sudo sh + - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly script: - rustc --version From 0fad06348462d03caa5e4ef15fbe48c2415b469d Mon Sep 17 00:00:00 2001 From: "Robbie Harwood (frozencemetery)" Date: Mon, 6 Apr 2015 23:23:49 -0400 Subject: [PATCH 0204/1122] Some grammar fixups --- examples/clone/input.md | 2 +- examples/closures/input.md | 6 +++--- examples/file/create/input.md | 6 +++--- examples/file/input.md | 6 +++--- examples/hof/input.md | 4 ++-- examples/macros/repeat/input.md | 2 +- examples/process/input.md | 4 ++-- examples/simd/input.md | 2 +- examples/vec/input.md | 12 ++++++------ 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/clone/input.md b/examples/clone/input.md index 7372ce8b56..4cc536156d 100644 --- a/examples/clone/input.md +++ b/examples/clone/input.md @@ -1,6 +1,6 @@ When dealing with resources, the default behavior is to transfer them during assignments or function calls. Sometimes the intention is to make a copy of the -resource, this can be accomplished by calling the `clone` method, defined in +resource. This can be accomplished by calling the `clone` method, defined in the `Clone` trait. {clone.play} diff --git a/examples/closures/input.md b/examples/closures/input.md index 835b824600..55685fbb48 100644 --- a/examples/closures/input.md +++ b/examples/closures/input.md @@ -1,10 +1,10 @@ Closures are special functions that can capture the variables available in the surrounding scope. Closures consist of three parts: -* A list of arguments enclosed by pipes `|`, these arguments can optionally be +* A list of arguments enclosed by pipes `|`. These arguments can optionally be type annotated, but usually the compiler will infer their types -* Optionally the return type using an arrow `->`, again this usually gets +* Optionally the return type using an arrow `->`. Again, this usually gets inferred -* A block, the last expression is the return value +* A block. The last expression is the return value {closures.play} diff --git a/examples/file/create/input.md b/examples/file/create/input.md index 462b030739..3088e39108 100644 --- a/examples/file/create/input.md +++ b/examples/file/create/input.md @@ -1,5 +1,6 @@ -The `create` static method opens a file in write-only mode. If the file already -existed, the old content is destroyed, otherwise a new file is created. +The `create` static method opens a file in write-only mode. If the file +already existed, the old content is destroyed. Otherwise, a new file is +created. {create.play} @@ -24,4 +25,3 @@ failure conditions) There is also a more generic `open_mode` method that can open files in other modes like: read+write, append, etc. - diff --git a/examples/file/input.md b/examples/file/input.md index 5f2166bcf4..c98c3c714e 100644 --- a/examples/file/input.md +++ b/examples/file/input.md @@ -4,6 +4,6 @@ descriptor), and gives read and/or write access to the underlying file. Since many things can go wrong when doing file I/O, all the `File` methods return the `IoResult` type, which is an alias for `Result`. -This makes the failure of all I/O operations *explicit*, thanks to -this the programmer can see all the failure paths, and is encouraged to handle -them in a proactive manner. +This makes the failure of all I/O operations *explicit*. Thanks to this, the +programmer can see all the failure paths, and is encouraged to handle them in +a proactive manner. diff --git a/examples/hof/input.md b/examples/hof/input.md index 644846e7a0..20215b05d8 100644 --- a/examples/hof/input.md +++ b/examples/hof/input.md @@ -1,5 +1,5 @@ -Rust provides Higher Order Functions (HOF), these are functions that take a -closure as an argument to produce a more useful function. HOFs and lazy +Rust provides Higher Order Functions (HOF). These are functions that take a +closure as an argument to produce a more useful function. HOFs and lazy iterators give Rust its functional flavor. {hof.play} diff --git a/examples/macros/repeat/input.md b/examples/macros/repeat/input.md index 13ff391f7b..2c8886f65b 100644 --- a/examples/macros/repeat/input.md +++ b/examples/macros/repeat/input.md @@ -1,4 +1,4 @@ -Macros can use `+` in the argument list, to indicate that an argument may +Macros can use `+` in the argument list to indicate that an argument may repeat at least once, or `*`, to indicate that the argument may repeat zero or more times. diff --git a/examples/process/input.md b/examples/process/input.md index 671388d83d..820d906fd0 100644 --- a/examples/process/input.md +++ b/examples/process/input.md @@ -1,5 +1,5 @@ -The `ProcessOutput` struct represents the output of a finished child process. -And the `Command` struct is a process builder. +The `ProcessOutput` struct represents the output of a finished child process, +and the `Command` struct is a process builder. {process.play} diff --git a/examples/simd/input.md b/examples/simd/input.md index b58c4e2e98..312f14886f 100644 --- a/examples/simd/input.md +++ b/examples/simd/input.md @@ -1,5 +1,5 @@ Rust provides experimental support for SIMD vectors. These SIMD vectors are -exposed as structs (`f32x4`, `u8x16`, etc.), that implement basic operations +exposed as structs (`f32x4`, `u8x16`, etc.) that implement basic operations (`+`, `-`, `*`, etc) using SIMD instructions under the hood. {simd.rs} diff --git a/examples/vec/input.md b/examples/vec/input.md index 0c0bc5ad13..370229c862 100644 --- a/examples/vec/input.md +++ b/examples/vec/input.md @@ -1,9 +1,9 @@ -Vectors are re-sizable arrays, like slices their size is not known at compile -time, but they can grow or shrink at anytime. A vector is represented using -3 words: a pointer to the data, its length and its capacity. The capacity -indicates how much memory is reserved for the vector, the vector can grow as -long as the length is smaller than the capacity, when this threshold needs to -be surpassed, the vector gets reallocated with a bigger capacity. +Vectors are re-sizable arrays. Like slices, their size is not known at compile +time, but they can grow or shrink at any time. A vector is represented using +3 words: a pointer to the data, its length, and its capacity. The capacity +indicates how much memory is reserved for the vector. The vector can grow as +long as the length is smaller than the capacity. When this threshold needs to +be surpassed, the vector is reallocated with a larger capacity. {vec.play} From 87e7f071a6eb924dcec96cfdc31cec7e6badef8d Mon Sep 17 00:00:00 2001 From: woxtu Date: Wed, 8 Apr 2015 23:27:49 +0900 Subject: [PATCH 0205/1122] file: fix some comments --- examples/file/create/create.rs | 4 ++-- examples/file/input.md | 2 +- examples/file/open/open.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/file/create/create.rs b/examples/file/create/create.rs index 0ffb9d8cca..9e6bd870a1 100644 --- a/examples/file/create/create.rs +++ b/examples/file/create/create.rs @@ -16,7 +16,7 @@ fn main() { let path = Path::new("out/lorem_ipsum.txt"); let display = path.display(); - // Open a file in write-only mode, returns `IoResult` + // Open a file in write-only mode, returns `io::Result` let mut file = match File::create(&path) { Err(why) => panic!("couldn't create {}: {}", display, @@ -24,7 +24,7 @@ fn main() { Ok(file) => file, }; - // Write the `LOREM_IPSUM` string to `file`, returns `IoResult<()>` + // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>` match file.write_all(LOREM_IPSUM.as_bytes()) { Err(why) => { panic!("couldn't write to {}: {}", display, diff --git a/examples/file/input.md b/examples/file/input.md index c98c3c714e..2dd1039471 100644 --- a/examples/file/input.md +++ b/examples/file/input.md @@ -2,7 +2,7 @@ The `File` struct represents a file that has been opened (it wraps a file descriptor), and gives read and/or write access to the underlying file. Since many things can go wrong when doing file I/O, all the `File` methods -return the `IoResult` type, which is an alias for `Result`. +return the `io::Result` type, which is an alias for `Result`. This makes the failure of all I/O operations *explicit*. Thanks to this, the programmer can see all the failure paths, and is encouraged to handle them in diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index bce6763936..70ce3c1f30 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -8,15 +8,15 @@ fn main() { let path = Path::new("hello.txt"); let display = path.display(); - // Open the path in read-only mode, returns `IoResult` + // Open the path in read-only mode, returns `io::Result` let mut file = match File::open(&path) { - // The `desc` field of `IoError` is a string that describes the error + // The `description` method of `io::Error` returns a string that describes the error Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)), Ok(file) => file, }; - // Read the file contents into a string, returns `IoResult` + // Read the file contents into a string, returns `io::Result` let mut s = String::new(); match file.read_to_string(&mut s) { Err(why) => panic!("couldn't read {}: {}", display, From cccd92621467141097d80f742186467776af6c4a Mon Sep 17 00:00:00 2001 From: woxtu Date: Thu, 9 Apr 2015 01:28:34 +0900 Subject: [PATCH 0206/1122] file/open: add a newline --- examples/file/open/open.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/file/open/open.rs b/examples/file/open/open.rs index 70ce3c1f30..79eb46074d 100644 --- a/examples/file/open/open.rs +++ b/examples/file/open/open.rs @@ -10,7 +10,8 @@ fn main() { // Open the path in read-only mode, returns `io::Result` let mut file = match File::open(&path) { - // The `description` method of `io::Error` returns a string that describes the error + // The `description` method of `io::Error` returns a string that + // describes the error Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)), Ok(file) => file, From 5d19ff02764ef848a01ff8bb33f759f03373ff9b Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Apr 2015 15:13:45 -0400 Subject: [PATCH 0207/1122] Fix breakage from 97f24a85965. Make hof cleaner. --- Cargo.lock | 4 ++-- examples/hof/hof.rs | 24 +++++++----------------- src/example.rs | 5 +++-- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a40f671045..1409c1cbaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] diff --git a/examples/hof/hof.rs b/examples/hof/hof.rs index 563d7d35ed..ba2edd7337 100644 --- a/examples/hof/hof.rs +++ b/examples/hof/hof.rs @@ -1,18 +1,14 @@ -#![feature(step_by)] #![feature(core)] -// The `AdditiveIterator` trait adds the `sum` method to iterators -use std::iter::AdditiveIterator; - fn main() { println!("Find the sum of all the squared odd numbers under 1000"); - let upper = 1000u32; + let upper = 1000; // Imperative approach // Declare accumulator variable let mut acc = 0; // Iterate: 0, 1, 2, ... to infinity - for n in (0u32..).step_by(1) { + for n in 0.. { // Square the number let n_squared = n * n; @@ -27,17 +23,11 @@ fn main() { println!("imperative style: {}", acc); // Functional approach - let sum_of_squared_odd_numbers = - // All natural numbers - (0u32..).step_by(1). - // Squared - map(|n| n * n). - // Below upper limit - take_while(|&n| n < upper). - // That are odd - filter(|n| is_odd(*n)). - // Sum them - sum(); + let sum_of_squared_odd_numbers: u32 = + (0..).map(|n| n * n) // All natural numbers squared + .take_while(|&n| n < upper) // Below upper limit + .filter(|n| is_odd(*n)) // That are odd + .sum(); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); } diff --git a/src/example.rs b/src/example.rs index 6697a26e33..cf4cf0f795 100644 --- a/src/example.rs +++ b/src/example.rs @@ -1,6 +1,5 @@ use markdown::Markdown; use rustc_serialize::{Decodable,json}; -use std::iter::AdditiveIterator; use std::iter::repeat; use std::sync::mpsc; use std::io::prelude::*; @@ -36,7 +35,9 @@ impl Example { pub fn count(&self) -> usize { match self.children { None => 1, - Some(ref children) => 1 + children.iter().map(|c| c.count()).sum(), + Some(ref children) => 1 + children.iter() + .map(|c| c.count()) + .sum::(), } } From 23ea6d4ed082a8d1ddf3478153e2da34736e879b Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Apr 2015 17:14:10 -0400 Subject: [PATCH 0208/1122] Use nightly playpen --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index d08a4b26e4..5afe0e5419 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -159,7 +159,7 @@ function escapeHTML(unsafe) { function runProgram(program, callback) { var req = new XMLHttpRequest(); var data = JSON.stringify({ - version: "master", + version: "nightly", optimize: "0", code: program }); From 591f48c3f9c6e244651c14eaf606cedbf86a9ebb Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Apr 2015 20:25:54 -0400 Subject: [PATCH 0209/1122] Add const to constants. Split off static lifetimes. --- examples/constants/constants.rs | 13 ++------- examples/constants/input.md | 28 +++++++++++++------ examples/lifetime/static_lifetime/input.md | 13 +++++++++ .../static_lifetime/static_lifetime.rs | 15 ++++++++++ examples/structure.json | 5 ++-- 5 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 examples/lifetime/static_lifetime/input.md create mode 100644 examples/lifetime/static_lifetime/static_lifetime.rs diff --git a/examples/constants/constants.rs b/examples/constants/constants.rs index 3cd3d93a94..5a22bf967c 100644 --- a/examples/constants/constants.rs +++ b/examples/constants/constants.rs @@ -1,5 +1,6 @@ +// Globals are declared outside all other scopes. static LANGUAGE: &'static str = "Rust"; -static THRESHOLD: i32 = 10; +const THRESHOLD: i32 = 10; fn is_big(n: i32) -> bool { // Access constant in some function @@ -14,15 +15,7 @@ fn main() { println!("The threshold is {}", THRESHOLD); println!("{} is {}", n, if is_big(n) { "big" } else { "small" }); - // Error! Cannot modify a static item + // Error! Cannot modify a `const`. THRESHOLD = 5; // FIXME ^ Comment out this line - - { - // String literals are references to read-only memory - let _static_string: &'static str = "In read-only memory"; - - // When `_static_string` goes out of scope, we can no longer refer to - // the underlying data, but the string remains in the read-only memory - } } diff --git a/examples/constants/input.md b/examples/constants/input.md index d3f8eed72a..5a46644a88 100644 --- a/examples/constants/input.md +++ b/examples/constants/input.md @@ -1,12 +1,22 @@ -Constants can be declared in the global scope using the `static` keyword, the -type annotation is obligatory in this case. These constants are placed in a -read-only section of the memory and can be accessed in any other part of the -program. +Rust has two different types of constants which can be declared in any scope +including global. Both require explicit type annotation: -String literals like `"string"` can also be assigned to static variables. These -variables have type signature `&'static str`, and are references to strings -allocated in read-only memory. `'static` is a special lifetime that outlives -all the other lifetimes, and indicates that the referenced data is available in -all the scopes. +* `const`: An unchangable value (the common case). +* `static`: A possibly `mut`able variable with [`'static`][static] lifetime. + +One special case is the `"string"` literal. It can be assigned directly to a +`static` variable without modification because it's type signature: +`&'static str` has the required lifetime of `'static`. All other reference +types must be specifically annotated so that they fulfill the `'static` +lifetime. This may seem minor though because the required explicit annotation +hides the distinction. {constants.play} + +### See also: + +[The `const`/`static` RFC]( +https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md), +[`'static` lifetime][static] + +[static]: ./lifetime/static_lifetime.html diff --git a/examples/lifetime/static_lifetime/input.md b/examples/lifetime/static_lifetime/input.md new file mode 100644 index 0000000000..4f1cfb4701 --- /dev/null +++ b/examples/lifetime/static_lifetime/input.md @@ -0,0 +1,13 @@ +A `'static` lifetime is one which lasts for the lifetime of the running +program. There are two ways to make a variable with `'static` lifetime: + +* Make a `"string"` literal which has type: `&'static str`. +* Make a constant with the `static` declaration. + +{static_lifetime.play} + +### See also: + +[`'static` constants][static_const] + +[static_const]: ./constants.html diff --git a/examples/lifetime/static_lifetime/static_lifetime.rs b/examples/lifetime/static_lifetime/static_lifetime.rs new file mode 100644 index 0000000000..bd34d5ea0a --- /dev/null +++ b/examples/lifetime/static_lifetime/static_lifetime.rs @@ -0,0 +1,15 @@ +static NUM: i32 = 18; + +fn main() { + { + // String literals are references to read-only memory + let static_string = "In read-only memory"; + + // When `_static_string` goes out of scope, we can no longer refer to + // the underlying data, but the string remains in the read-only memory + println!("static_string holds: {}", static_string); + } + + println!("but now it's gone."); + println!("NUM: {} is still around though!", NUM); +} diff --git a/examples/structure.json b/examples/structure.json index a676b8d7eb..6ed7b100d9 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -80,9 +80,10 @@ { "id": "lifetime", "title": "Lifetimes", "children": [ { "id": "borrow", "title": "The borrow checker", "children": null }, { "id": "fn", "title": "Functions", "children": null }, - { "id": "struct", "title": "Structs", "children": null } + { "id": "struct", "title": "Structs", "children": null }, + { "id": "static_lifetime", "title": "static", "children": null } ] }, - { "id": "constants", "title": "Global constants", "children": null }, + { "id": "constants", "title": "constants", "children": null }, { "id": "methods", "title": "Methods", "children": null }, { "id": "enum", "title": "Enums", "children": [ { "id": "c_like", "title": "C-like", "children": null } From 7e8d740e71d59e34633b8258ab62402971fdc511 Mon Sep 17 00:00:00 2001 From: mdinger Date: Tue, 14 Apr 2015 00:34:22 -0400 Subject: [PATCH 0210/1122] Fix build failure by adding prefix --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3d87af3af6..0daa71984d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: true install: - - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly + - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --prefix=/usr --channel=nightly script: - rustc --version From 3923fd0ee1f1ad7aef09e798c98bd7d197f7c767 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 15 Apr 2015 11:31:13 -0400 Subject: [PATCH 0211/1122] Update rust --- Cargo.lock | 4 ++-- examples/threads/threads.rs | 2 ++ src/main.rs | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1409c1cbaa..5ff5faa3f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index b476976b84..f61d14e0d2 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -1,3 +1,5 @@ +#![feature(scoped)] + use std::thread; static NTHREADS: i32 = 10; diff --git a/src/main.rs b/src/main.rs index d3d0826c3c..86ba682b6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(core)] +#![feature(scoped)] #![deny(warnings)] #![feature(plugin)] From 6b9a79e7bf53e5d89e02288c0b34aa5cbab5d90b Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 15 Apr 2015 11:31:32 -0400 Subject: [PATCH 0212/1122] Trim timer to what remains in std --- examples/timers/timers.rs | 42 ++++++--------------------------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs index 7a29178253..695f14611b 100644 --- a/examples/timers/timers.rs +++ b/examples/timers/timers.rs @@ -1,45 +1,15 @@ -#![feature(old_io)] -#![feature(std_misc)] -#![feature(step_by)] - -use std::old_io::{timer, Timer}; -use std::time::duration::Duration; -use std::sync::mpsc; +use std::thread; fn main() { - let interval = Duration::milliseconds(1000); - // Create a timer object - let mut timer = Timer::new().unwrap(); - - // Create a one-shot notification - // (superfluous type annotation) - let oneshot: mpsc::Receiver<()> = timer.oneshot(interval); + let interval = 1000; - println!("Wait {} ms...", interval.num_milliseconds()); - - // Block the thread until notification arrives - let _ = oneshot.recv(); + println!("Block for {} ms...", interval); + thread::park_timeout_ms(interval); println!("Done"); - println!("Sleep for {} ms...", interval.num_milliseconds()); - - // This is equivalent to `timer.oneshot(interval).recv()` - timer::sleep(interval); + println!("Sleep for {} ms...", interval); + thread::sleep_ms(interval); println!("Done"); - - // The same timer can be used to generate periodic notifications - // (superfluous type annotation) - let metronome: mpsc::Receiver<()> = timer.periodic(interval); - - println!("Countdown"); - for i in (5i32..0).step_by(-1) { - // This loop will run once every second - let _ = metronome.recv(); - - println!("{}", i); - } - let _ = metronome.recv(); - println!("Ignition!"); } From b7b9972eab3f82b0923756179d0cb0f4284f7cf7 Mon Sep 17 00:00:00 2001 From: petrcech Date: Fri, 17 Apr 2015 10:41:17 +0200 Subject: [PATCH 0213/1122] type/cast: fix math in comment add 3rd subtraction to fix the equation --- examples/type/cast/cast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/type/cast/cast.rs b/examples/type/cast/cast.rs index 87a344afb5..739cf0033d 100644 --- a/examples/type/cast/cast.rs +++ b/examples/type/cast/cast.rs @@ -18,7 +18,7 @@ fn main() { // 1000 already fits in a u16 println!("1000 as a u16 is: {}", 1000 as u16); - // 1000 - 256 - 256 = 232 + // 1000 - 256 - 256 -256 = 232 println!("1000 as a u8 is : {}", 1000 as u8); // -1 + 256 = 255 println!(" -1 as a u8 is : {}", (-1i8) as u8); From 0a49fe7a7e58ca645e342ca8c951a6656f08466a Mon Sep 17 00:00:00 2001 From: limhiaoing Date: Fri, 17 Apr 2015 21:12:53 +0800 Subject: [PATCH 0214/1122] lifetime/struct: Change int to i32 --- examples/lifetime/struct/struct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lifetime/struct/struct.rs b/examples/lifetime/struct/struct.rs index ec20f2bd94..9b8f1fb4dc 100644 --- a/examples/lifetime/struct/struct.rs +++ b/examples/lifetime/struct/struct.rs @@ -1,7 +1,7 @@ // First attempt: No explicit lifetimes // Error! Compiler needs explicit lifetime //struct Singleton { - //one: &mut int, + //one: &mut i32, //} // TODO ^ Try uncommenting this struct From 3fe82d87ded195080ca51b2ae7a357b2531827e9 Mon Sep 17 00:00:00 2001 From: Lyle Mantooth Date: Fri, 17 Apr 2015 11:33:23 -0400 Subject: [PATCH 0215/1122] Make macros/dry tests pass. As written, the tests were failing because `test!` was building vectors of different sizes instead of building vectors filled with different values. Swapping the variable names into the right methods and fixing their types allows the tests to pass. --- examples/macros/dry/dry.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index 4cf7fb2a76..81205fc79c 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -46,10 +46,10 @@ mod test { ($func: ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { - for size in 0u32..10 { - let mut x: Vec<_> = iter::repeat(size).take($x).collect(); - let y: Vec<_> = iter::repeat(size).take($y).collect(); - let z: Vec<_> = iter::repeat(size).take($z).collect(); + for size in 0usize..10 { + let mut x: Vec<_> = iter::repeat($x).take(size).collect(); + let y: Vec<_> = iter::repeat($y).take(size).collect(); + let z: Vec<_> = iter::repeat($z).take(size).collect(); super::$func(&mut x, &y); @@ -60,8 +60,8 @@ mod test { } // test add_assign, mul_assign and sub_assign - test!(add_assign, 1usize, 2usize, 3usize); - test!(mul_assign, 2usize, 3usize, 6usize); - test!(sub_assign, 3usize, 2usize, 1usize); + test!(add_assign, 1u32, 2u32, 3u32); + test!(mul_assign, 2u32, 3u32, 6u32); + test!(sub_assign, 3u32, 2u32, 1u32); } From a7731c6e9661c76ea963ee7428a9b3a363e2f55b Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 17 Apr 2015 15:31:43 -0400 Subject: [PATCH 0216/1122] Delete timers because no longer in std --- examples/structure.json | 1 - examples/timers/input.md | 23 ----------------------- examples/timers/timers.rs | 15 --------------- 3 files changed, 39 deletions(-) delete mode 100644 examples/timers/input.md delete mode 100644 examples/timers/timers.rs diff --git a/examples/structure.json b/examples/structure.json index 6ed7b100d9..da12543b07 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -105,7 +105,6 @@ { "id": "clone", "title": "Clone", "children": null }, { "id": "threads", "title": "Threads", "children": null }, { "id": "channels", "title": "Channels", "children": null }, - { "id": "timers", "title": "Timers", "children": null }, { "id": "result", "title": "`Result`", "children": [ { "id": "try", "title": "`try!`", "children": null } ] }, diff --git a/examples/timers/input.md b/examples/timers/input.md deleted file mode 100644 index 4221014f92..0000000000 --- a/examples/timers/input.md +++ /dev/null @@ -1,23 +0,0 @@ -A `Timer` represents an underlying OS timer, and can generate *one-shot* and -*periodic* notifications via the `Receiver` endpoint of a channel. - -{timers.play} - -The playpen has a time limit, so you won't be able to see the (full) output in -the editor. Here's the output you should see, if you run this on a computer. - -``` -$ rustc timers.rs && time ./timers -Wait 1000 ms... -Done -Sleep for 1000 ms... -Done -Countdown -5 -4 -3 -2 -1 -Ignition! -./timers 0.00s user 0.00s system 0% cpu 8.003 total -``` diff --git a/examples/timers/timers.rs b/examples/timers/timers.rs deleted file mode 100644 index 695f14611b..0000000000 --- a/examples/timers/timers.rs +++ /dev/null @@ -1,15 +0,0 @@ -use std::thread; - -fn main() { - let interval = 1000; - - println!("Block for {} ms...", interval); - thread::park_timeout_ms(interval); - - println!("Done"); - - println!("Sleep for {} ms...", interval); - thread::sleep_ms(interval); - - println!("Done"); -} From 54721b9bc13a7e91e281614402e20a90bfd01e79 Mon Sep 17 00:00:00 2001 From: Janus Troelsen Date: Sat, 18 Apr 2015 17:48:07 +0200 Subject: [PATCH 0217/1122] Don't explicitly prefer Courier New It looks worse than the default font on FreeType systems with low DPI. --- node_modules/gitbook-plugin-rust-playpen/book/editor.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index b45d59da49..543deae95d 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -16,7 +16,7 @@ width: 100%; min-height: 72px; font-size: 13px; - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-family: Menlo, Monaco, Consolas, monospace; white-space: pre-wrap; } @@ -27,7 +27,7 @@ padding: 10px; display: none; border-radius: 4px; - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-family: Menlo, Monaco, Consolas, monospace; white-space: normal; } From b6949a72e43b7c27d1e7b5d7228847ea14234b62 Mon Sep 17 00:00:00 2001 From: pyed Date: Mon, 20 Apr 2015 10:40:45 +0300 Subject: [PATCH 0218/1122] flow control/match/destructuring/enums: fix typo --- .../flow_control/match/destructuring/destructure_enum/enum.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs index 1ca47109d6..8e9e841790 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/enum.rs +++ b/examples/flow_control/match/destructuring/destructure_enum/enum.rs @@ -23,7 +23,7 @@ fn main() { Color::Blue => println!("The color is Blue!"), Color::Green => println!("The color is Green!"), Color::RGB(r, g, b) => { - println!("Red: {:?}, green: {:?}, and blue: {:?}!:", r, g, b); + println!("Red: {:?}, green: {:?}, and blue: {:?}!", r, g, b); }, // Don't need another arm because all variants have been examined } From a2efbf84397671e44d59abbc82dd640633bad94a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 20 Apr 2015 13:49:36 -0400 Subject: [PATCH 0219/1122] small spacing fix --- examples/type/cast/cast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/type/cast/cast.rs b/examples/type/cast/cast.rs index 739cf0033d..cb6b0139e4 100644 --- a/examples/type/cast/cast.rs +++ b/examples/type/cast/cast.rs @@ -18,7 +18,7 @@ fn main() { // 1000 already fits in a u16 println!("1000 as a u16 is: {}", 1000 as u16); - // 1000 - 256 - 256 -256 = 232 + // 1000 - 256 - 256 - 256 = 232 println!("1000 as a u8 is : {}", 1000 as u8); // -1 + 256 = 255 println!(" -1 as a u8 is : {}", (-1i8) as u8); From 0b2b464e3cf70069ccc7a8dfdce2e7d49ec7e23e Mon Sep 17 00:00:00 2001 From: pyed Date: Wed, 22 Apr 2015 10:31:12 +0300 Subject: [PATCH 0220/1122] generics/phantom types: fix typos minor typos --- examples/generics/phantom/phantom.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs index 9c7d5d859c..997e63b87f 100644 --- a/examples/generics/phantom/phantom.rs +++ b/examples/generics/phantom/phantom.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -// Generic tuplestruct with same types in both +// Generic tuple struct with same types in both // generic
and definition (A,) struct Tuple(A,); @@ -21,7 +21,7 @@ fn main() { // We can create similar types without carrying around extra info // PhantomTuple specialized to - let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); + let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); // PhantomTuple specialized to let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); @@ -42,6 +42,6 @@ fn main() { // Error: type mismatch so these cannot be compared //println!("_struct1 == _struct2 yields: {}", - // _struct2 == _struct2); + // _struct1 == _struct2); } From 1116546ffe433abca3dc7d72802699570d065b03 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 22 Apr 2015 22:34:12 -0400 Subject: [PATCH 0221/1122] Update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ff5faa3f5..503e6ea11e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] From 35555c39ecbc77e73fead86bba4893b7669483aa Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 22 Apr 2015 22:34:34 -0400 Subject: [PATCH 0222/1122] Give more precise build instructions --- README.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e6f264b9f4..209c8cac9f 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,24 @@ See [CONTRIBUTING.md][how-to-contribute]. ## How to generate the static site -First, make certain you install `nodejs` on Debian based distributions, or -`node` on non-Debian distros. After installation, if you use a Debian based -distro (i.e. Ubuntu), run: +### Debian (Ubuntu) prerequisites - sudo ln -s /usr/bin/nodejs /usr/bin/node +Install Rust [nightly](http://www.rust-lang.org/install.html) and +run: -Then run: +``` +sudo apt-get install nodejs npm subversion +sudo ln -s /usr/bin/nodejs /usr/bin/node +``` + +### Non-Debian prerequisites + +Install Rust [nightly](http://www.rust-lang.org/install.html), +`node`, `npm`, and `subversion`. + +### Build instructions + +Run: ``` make all From ac7ea18778087d931996165835f8f6e8d9df0629 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 22 Apr 2015 22:43:06 -0400 Subject: [PATCH 0223/1122] Revert "Fix build failure by adding prefix" This reverts commit 7e8d740e71d59e34633b8258ab62402971fdc511. It was fixed upstream. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0daa71984d..3d87af3af6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: true install: - - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --prefix=/usr --channel=nightly + - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly script: - rustc --version From 051b198d4c16483a4960bab9d11ebbeefef6018e Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 23 Apr 2015 14:12:28 -0400 Subject: [PATCH 0224/1122] Update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 503e6ea11e..f43cb65ed3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -13,6 +13,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" From 5e4887500ce258a9322dd90140e7b4bfcf39b962 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 23 Apr 2015 14:26:30 -0400 Subject: [PATCH 0225/1122] Fix warning --- examples/str/str.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/str/str.rs b/examples/str/str.rs index 761fc530f0..af2bb6720d 100644 --- a/examples/str/str.rs +++ b/examples/str/str.rs @@ -1,5 +1,4 @@ #![feature(collections)] -#![feature(str_words)] fn main() { // (all the type annotations are superfluous) @@ -9,7 +8,7 @@ fn main() { // Iterate over words in reverse, no new string is allocated println!("Words in reverse"); - for word in pangram.words().rev() { + for word in pangram.split_whitespace().rev() { println!("> {}", word); } From 585535f3cc656a22f03b288d337dafd55fd6a374 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 24 Apr 2015 13:24:33 -0400 Subject: [PATCH 0226/1122] Remove old_io example --- examples/mod/mod.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/mod/mod.rs b/examples/mod/mod.rs index 7cff97e3c1..b8d2b1ad4d 100644 --- a/examples/mod/mod.rs +++ b/examples/mod/mod.rs @@ -22,12 +22,6 @@ mod my { fn main() { function(); - // Items inside a module can be called using their full path - // The `println` function lives in the `stdio` module - // The `stdio` module lives in the `io` module - // And the `io` module lives in the `std` crate - std::old_io::stdio::println("Hello World!"); - // Error! `my::function` is private my::function(); // TODO ^ Comment out this line From ddde9e383ac74f8f4a97603932d11918ee263545 Mon Sep 17 00:00:00 2001 From: Tair Rzayev Date: Thu, 30 Apr 2015 16:14:15 +0300 Subject: [PATCH 0227/1122] threads/threads.rs: change NTHREADS type to usize That is also consistent with the type used in channels/channels.rs --- examples/threads/threads.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index f61d14e0d2..5d0cc56121 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -2,7 +2,7 @@ use std::thread; -static NTHREADS: i32 = 10; +static NTHREADS: usize = 10; // This is the `main` thread fn main() { From 20dd84285162e4545899ca22f60e7cf50b4102a0 Mon Sep 17 00:00:00 2001 From: Tair Rzayev Date: Thu, 30 Apr 2015 18:48:18 +0300 Subject: [PATCH 0228/1122] Revert commit ddde9e383ac74f8f4a97603932d11918ee263545 --- examples/threads/threads.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/threads/threads.rs b/examples/threads/threads.rs index 5d0cc56121..f61d14e0d2 100644 --- a/examples/threads/threads.rs +++ b/examples/threads/threads.rs @@ -2,7 +2,7 @@ use std::thread; -static NTHREADS: usize = 10; +static NTHREADS: i32 = 10; // This is the `main` thread fn main() { From cf0ac9d92e6f9b1621188484bdbd045fde38060b Mon Sep 17 00:00:00 2001 From: Tair Rzayev Date: Thu, 30 Apr 2015 18:43:06 +0300 Subject: [PATCH 0229/1122] channels/channels.rs: change NTHREADS type to usize That is also consistent with the type used in threads/threads.rs --- examples/channels/channels.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/channels/channels.rs b/examples/channels/channels.rs index db22d4807c..4e265c5359 100644 --- a/examples/channels/channels.rs +++ b/examples/channels/channels.rs @@ -2,13 +2,13 @@ use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; use std::thread; -static NTHREADS: usize = 3; +static NTHREADS: i32 = 3; fn main() { // Channels have two endpoints: the `Sender` and the `Receiver`, // where `T` is the type of the message to be transferred // (type annotation is superfluous) - let (tx, rx): (Sender, Receiver) = mpsc::channel(); + let (tx, rx): (Sender, Receiver) = mpsc::channel(); for id in 0..NTHREADS { // The sender endpoint can be copied @@ -27,7 +27,7 @@ fn main() { } // Here, all the messages are collected - let mut ids = Vec::with_capacity(NTHREADS); + let mut ids = Vec::with_capacity(NTHREADS as usize); for _ in 0..NTHREADS { // The `recv` method picks a message from the channel // `recv` will block the current thread if there no messages available From 16f470e99a7eef70a01ad55841f8fa0521fcc633 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 29 Apr 2015 22:25:24 -0400 Subject: [PATCH 0230/1122] Update cargo lock --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f43cb65ed3..849b7d4c44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,17 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" From 13f494b1046eeb8ecfe84b82c9899cb02171b400 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 30 Apr 2015 00:26:41 -0400 Subject: [PATCH 0231/1122] Use 100 character line length like all rust programs --- check-line-length.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-line-length.sh b/check-line-length.sh index 902719683a..b42ce47701 100755 --- a/check-line-length.sh +++ b/check-line-length.sh @@ -5,9 +5,9 @@ WHITELIST=( ./src/playpen.rs ) -echo "Checking if any rust file has a line longer than 79 characters" +echo "Checking if any rust file has a line longer than 99 characters" -suspects=$(find . -name '*.rs' | xargs grep -El ".{80}") +suspects=$(find . -name '*.rs' | xargs grep -El ".{100}") status=$? any_offender=false From c5e6e57a72ce5ec725809cfba4d2b25bbc64bf24 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 14:29:57 -0400 Subject: [PATCH 0232/1122] Reorganize table of contents; use 4 space tabs --- examples/{type => cast}/alias/alias.rs | 0 examples/{type => cast}/alias/input.md | 0 examples/{type => }/cast/cast.rs | 0 .../{type => cast}/inference/inference.rs | 0 examples/{type => cast}/inference/input.md | 0 examples/{type => }/cast/input.md | 0 examples/{type => cast}/literals/input.md | 0 examples/{type => cast}/literals/literals.rs | 0 .../{ => custom_types}/constants/constants.rs | 0 .../{ => custom_types}/constants/input.md | 0 .../{ => custom_types}/enum/c_like/c_like.rs | 0 .../{ => custom_types}/enum/c_like/input.md | 0 examples/{ => custom_types}/enum/enum.rs | 0 examples/{ => custom_types}/enum/input.md | 0 examples/custom_types/input.md | 1 + examples/{ => custom_types}/structs/input.md | 0 .../{ => custom_types}/structs/structs.rs | 0 .../structs/visibility/input.md | 0 .../structs/visibility/struct.rs | 0 examples/{ => fn}/closures/closures.rs | 0 examples/{ => fn}/closures/input.md | 0 examples/{ => fn}/hof/hof.rs | 0 examples/{ => fn}/hof/input.md | 0 examples/{ => fn}/methods/input.md | 0 examples/{ => fn}/methods/methods.rs | 0 examples/{ => hello}/comment/comment.rs | 0 examples/{ => hello}/comment/input.md | 0 examples/{ => hello/print}/fmt/input.md | 0 examples/{ => hello/print}/fmt/show.rs | 0 examples/{ => hello}/print/input.md | 0 examples/{ => hello}/print/print.rs | 0 .../{ => hello}/print/print_debug/debug.rs | 0 .../{ => hello}/print/print_debug/input.md | 0 .../print/print_display/display.rs | 0 .../{ => hello}/print/print_display/input.md | 0 examples/{ => meta}/bench/bench.rs | 0 examples/{ => meta}/bench/input.md | 0 .../doc_comment/doc_comment.rs | 0 .../{comment => meta}/doc_comment/input.md | 0 examples/meta/input.md | 1 + examples/{ => meta}/test/input.md | 0 examples/{ => meta}/test/unit_test.rs | 0 examples/{ => primitives}/array/array.rs | 0 examples/{ => primitives}/array/input.md | 0 examples/primitives/input.md | 1 + examples/{ => primitives}/literals/input.md | 0 .../{ => primitives}/literals/literals.rs | 0 examples/{ => primitives}/tuples/input.md | 0 examples/{ => primitives}/tuples/tuples.rs | 0 examples/{ => scope}/borrow/alias/alias.rs | 0 examples/{ => scope}/borrow/alias/input.md | 0 examples/{ => scope}/borrow/borrow.rs | 0 examples/{ => scope}/borrow/freeze/freeze.rs | 0 examples/{ => scope}/borrow/freeze/input.md | 0 examples/{ => scope}/borrow/input.md | 0 examples/{ => scope}/borrow/mut/input.md | 0 examples/{ => scope}/borrow/mut/mut.rs | 0 examples/{ => scope}/borrow/ref/input.md | 0 examples/{ => scope}/borrow/ref/ref.rs | 0 examples/scope/input.md | 1 + .../{ => scope}/lifetime/borrow/borrow.rs | 0 examples/{ => scope}/lifetime/borrow/input.md | 0 .../{ => scope}/lifetime/explicit/explicit.rs | 0 .../{ => scope}/lifetime/explicit/input.md | 0 examples/{ => scope}/lifetime/fn/fn.rs | 0 examples/{ => scope}/lifetime/fn/input.md | 0 examples/{ => scope}/lifetime/input.md | 0 .../lifetime/static_lifetime/input.md | 0 .../static_lifetime/static_lifetime.rs | 0 examples/{ => scope}/lifetime/struct/input.md | 0 .../{ => scope}/lifetime/struct/struct.rs | 0 examples/{ => scope}/move/input.md | 0 examples/{ => scope}/move/move.rs | 0 examples/{ => scope}/move/mut/input.md | 0 examples/{ => scope}/move/mut/mut.rs | 0 examples/{ => scope}/raii/input.md | 0 examples/{ => scope}/raii/raii.rs | 0 examples/{ => std}/box/box.rs | 0 examples/{ => std}/box/input.md | 0 .../hash/alt_key_types/alt_key_types.rs | 0 .../{ => std}/hash/alt_key_types/input.md | 0 examples/{ => std}/hash/hash.rs | 0 examples/{ => std}/hash/hashset/hashset.rs | 0 examples/{ => std}/hash/hashset/input.md | 0 examples/{ => std}/hash/input.md | 0 examples/std/input.md | 1 + examples/{ => std}/option/input.md | 0 examples/{ => std}/option/option.rs | 0 examples/{ => std}/panic/input.md | 0 examples/{ => std}/panic/panic.rs | 0 examples/{ => std}/result/input.md | 0 examples/{ => std}/result/result.rs | 0 examples/{ => std}/result/try/input.md | 0 examples/{ => std}/result/try/try.rs | 0 examples/{ => std}/str/input.md | 0 examples/{ => std}/str/str.rs | 0 examples/{ => std}/vec/input.md | 0 examples/{ => std}/vec/vec.rs | 0 examples/{ => std_misc}/arg/args.rs | 0 examples/{ => std_misc}/arg/getopts/echo.rs | 0 examples/{ => std_misc}/arg/getopts/input.md | 0 examples/{ => std_misc}/arg/getopts/test.sh | 0 .../{ => std_misc}/arg/getopts/testopt.rs | 0 examples/{ => std_misc}/arg/input.md | 0 examples/{ => std_misc}/arg/matching/input.md | 0 .../{ => std_misc}/arg/matching/match_args.rs | 0 examples/{ => std_misc}/channels/channels.rs | 0 examples/{ => std_misc}/channels/input.md | 0 examples/{ => std_misc}/ffi/ffi.rs | 0 examples/{ => std_misc}/ffi/input.md | 0 examples/{ => std_misc}/ffi/safe.rs | 0 examples/{ => std_misc}/file/create/create.rs | 0 examples/{ => std_misc}/file/create/input.md | 0 examples/{ => std_misc}/file/input.md | 0 examples/{ => std_misc}/file/open/input.md | 0 examples/{ => std_misc}/file/open/open.rs | 0 examples/{ => std_misc}/fs/fs.rs | 0 examples/{ => std_misc}/fs/input.md | 0 examples/std_misc/input.md | 1 + examples/{ => std_misc}/path/input.md | 0 examples/{ => std_misc}/path/path.rs | 0 examples/{ => std_misc}/process/input.md | 0 examples/{ => std_misc}/process/pipe/input.md | 0 examples/{ => std_misc}/process/pipe/pipe.rs | 0 examples/{ => std_misc}/process/process.rs | 0 examples/{ => std_misc}/process/wait/input.md | 0 examples/{ => std_misc}/process/wait/wait.rs | 0 examples/{ => std_misc}/simd/input.md | 0 examples/{ => std_misc}/simd/simd.rs | 0 examples/{ => std_misc}/simd/simd_add.rs | 0 examples/{ => std_misc}/threads/input.md | 0 examples/{ => std_misc}/threads/threads.rs | 0 examples/structure.json | 295 +++++++++--------- examples/{ => trait}/bounds/bounds.rs | 0 examples/{ => trait}/bounds/input.md | 0 examples/{ => trait}/clone/clone.rs | 0 examples/{ => trait}/clone/input.md | 0 examples/{ => trait}/drop/drop.rs | 0 examples/{ => trait}/drop/input.md | 0 examples/{ => trait}/iter/input.md | 0 examples/{ => trait}/iter/iter.rs | 0 examples/{ => trait}/ops/input.md | 0 examples/{ => trait}/ops/operator.rs | 0 143 files changed, 159 insertions(+), 142 deletions(-) rename examples/{type => cast}/alias/alias.rs (100%) rename examples/{type => cast}/alias/input.md (100%) rename examples/{type => }/cast/cast.rs (100%) rename examples/{type => cast}/inference/inference.rs (100%) rename examples/{type => cast}/inference/input.md (100%) rename examples/{type => }/cast/input.md (100%) rename examples/{type => cast}/literals/input.md (100%) rename examples/{type => cast}/literals/literals.rs (100%) rename examples/{ => custom_types}/constants/constants.rs (100%) rename examples/{ => custom_types}/constants/input.md (100%) rename examples/{ => custom_types}/enum/c_like/c_like.rs (100%) rename examples/{ => custom_types}/enum/c_like/input.md (100%) rename examples/{ => custom_types}/enum/enum.rs (100%) rename examples/{ => custom_types}/enum/input.md (100%) create mode 100644 examples/custom_types/input.md rename examples/{ => custom_types}/structs/input.md (100%) rename examples/{ => custom_types}/structs/structs.rs (100%) rename examples/{ => custom_types}/structs/visibility/input.md (100%) rename examples/{ => custom_types}/structs/visibility/struct.rs (100%) rename examples/{ => fn}/closures/closures.rs (100%) rename examples/{ => fn}/closures/input.md (100%) rename examples/{ => fn}/hof/hof.rs (100%) rename examples/{ => fn}/hof/input.md (100%) rename examples/{ => fn}/methods/input.md (100%) rename examples/{ => fn}/methods/methods.rs (100%) rename examples/{ => hello}/comment/comment.rs (100%) rename examples/{ => hello}/comment/input.md (100%) rename examples/{ => hello/print}/fmt/input.md (100%) rename examples/{ => hello/print}/fmt/show.rs (100%) rename examples/{ => hello}/print/input.md (100%) rename examples/{ => hello}/print/print.rs (100%) rename examples/{ => hello}/print/print_debug/debug.rs (100%) rename examples/{ => hello}/print/print_debug/input.md (100%) rename examples/{ => hello}/print/print_display/display.rs (100%) rename examples/{ => hello}/print/print_display/input.md (100%) rename examples/{ => meta}/bench/bench.rs (100%) rename examples/{ => meta}/bench/input.md (100%) rename examples/{comment => meta}/doc_comment/doc_comment.rs (100%) rename examples/{comment => meta}/doc_comment/input.md (100%) create mode 100644 examples/meta/input.md rename examples/{ => meta}/test/input.md (100%) rename examples/{ => meta}/test/unit_test.rs (100%) rename examples/{ => primitives}/array/array.rs (100%) rename examples/{ => primitives}/array/input.md (100%) create mode 100644 examples/primitives/input.md rename examples/{ => primitives}/literals/input.md (100%) rename examples/{ => primitives}/literals/literals.rs (100%) rename examples/{ => primitives}/tuples/input.md (100%) rename examples/{ => primitives}/tuples/tuples.rs (100%) rename examples/{ => scope}/borrow/alias/alias.rs (100%) rename examples/{ => scope}/borrow/alias/input.md (100%) rename examples/{ => scope}/borrow/borrow.rs (100%) rename examples/{ => scope}/borrow/freeze/freeze.rs (100%) rename examples/{ => scope}/borrow/freeze/input.md (100%) rename examples/{ => scope}/borrow/input.md (100%) rename examples/{ => scope}/borrow/mut/input.md (100%) rename examples/{ => scope}/borrow/mut/mut.rs (100%) rename examples/{ => scope}/borrow/ref/input.md (100%) rename examples/{ => scope}/borrow/ref/ref.rs (100%) create mode 100644 examples/scope/input.md rename examples/{ => scope}/lifetime/borrow/borrow.rs (100%) rename examples/{ => scope}/lifetime/borrow/input.md (100%) rename examples/{ => scope}/lifetime/explicit/explicit.rs (100%) rename examples/{ => scope}/lifetime/explicit/input.md (100%) rename examples/{ => scope}/lifetime/fn/fn.rs (100%) rename examples/{ => scope}/lifetime/fn/input.md (100%) rename examples/{ => scope}/lifetime/input.md (100%) rename examples/{ => scope}/lifetime/static_lifetime/input.md (100%) rename examples/{ => scope}/lifetime/static_lifetime/static_lifetime.rs (100%) rename examples/{ => scope}/lifetime/struct/input.md (100%) rename examples/{ => scope}/lifetime/struct/struct.rs (100%) rename examples/{ => scope}/move/input.md (100%) rename examples/{ => scope}/move/move.rs (100%) rename examples/{ => scope}/move/mut/input.md (100%) rename examples/{ => scope}/move/mut/mut.rs (100%) rename examples/{ => scope}/raii/input.md (100%) rename examples/{ => scope}/raii/raii.rs (100%) rename examples/{ => std}/box/box.rs (100%) rename examples/{ => std}/box/input.md (100%) rename examples/{ => std}/hash/alt_key_types/alt_key_types.rs (100%) rename examples/{ => std}/hash/alt_key_types/input.md (100%) rename examples/{ => std}/hash/hash.rs (100%) rename examples/{ => std}/hash/hashset/hashset.rs (100%) rename examples/{ => std}/hash/hashset/input.md (100%) rename examples/{ => std}/hash/input.md (100%) create mode 100644 examples/std/input.md rename examples/{ => std}/option/input.md (100%) rename examples/{ => std}/option/option.rs (100%) rename examples/{ => std}/panic/input.md (100%) rename examples/{ => std}/panic/panic.rs (100%) rename examples/{ => std}/result/input.md (100%) rename examples/{ => std}/result/result.rs (100%) rename examples/{ => std}/result/try/input.md (100%) rename examples/{ => std}/result/try/try.rs (100%) rename examples/{ => std}/str/input.md (100%) rename examples/{ => std}/str/str.rs (100%) rename examples/{ => std}/vec/input.md (100%) rename examples/{ => std}/vec/vec.rs (100%) rename examples/{ => std_misc}/arg/args.rs (100%) rename examples/{ => std_misc}/arg/getopts/echo.rs (100%) rename examples/{ => std_misc}/arg/getopts/input.md (100%) rename examples/{ => std_misc}/arg/getopts/test.sh (100%) rename examples/{ => std_misc}/arg/getopts/testopt.rs (100%) rename examples/{ => std_misc}/arg/input.md (100%) rename examples/{ => std_misc}/arg/matching/input.md (100%) rename examples/{ => std_misc}/arg/matching/match_args.rs (100%) rename examples/{ => std_misc}/channels/channels.rs (100%) rename examples/{ => std_misc}/channels/input.md (100%) rename examples/{ => std_misc}/ffi/ffi.rs (100%) rename examples/{ => std_misc}/ffi/input.md (100%) rename examples/{ => std_misc}/ffi/safe.rs (100%) rename examples/{ => std_misc}/file/create/create.rs (100%) rename examples/{ => std_misc}/file/create/input.md (100%) rename examples/{ => std_misc}/file/input.md (100%) rename examples/{ => std_misc}/file/open/input.md (100%) rename examples/{ => std_misc}/file/open/open.rs (100%) rename examples/{ => std_misc}/fs/fs.rs (100%) rename examples/{ => std_misc}/fs/input.md (100%) create mode 100644 examples/std_misc/input.md rename examples/{ => std_misc}/path/input.md (100%) rename examples/{ => std_misc}/path/path.rs (100%) rename examples/{ => std_misc}/process/input.md (100%) rename examples/{ => std_misc}/process/pipe/input.md (100%) rename examples/{ => std_misc}/process/pipe/pipe.rs (100%) rename examples/{ => std_misc}/process/process.rs (100%) rename examples/{ => std_misc}/process/wait/input.md (100%) rename examples/{ => std_misc}/process/wait/wait.rs (100%) rename examples/{ => std_misc}/simd/input.md (100%) rename examples/{ => std_misc}/simd/simd.rs (100%) rename examples/{ => std_misc}/simd/simd_add.rs (100%) rename examples/{ => std_misc}/threads/input.md (100%) rename examples/{ => std_misc}/threads/threads.rs (100%) rename examples/{ => trait}/bounds/bounds.rs (100%) rename examples/{ => trait}/bounds/input.md (100%) rename examples/{ => trait}/clone/clone.rs (100%) rename examples/{ => trait}/clone/input.md (100%) rename examples/{ => trait}/drop/drop.rs (100%) rename examples/{ => trait}/drop/input.md (100%) rename examples/{ => trait}/iter/input.md (100%) rename examples/{ => trait}/iter/iter.rs (100%) rename examples/{ => trait}/ops/input.md (100%) rename examples/{ => trait}/ops/operator.rs (100%) diff --git a/examples/type/alias/alias.rs b/examples/cast/alias/alias.rs similarity index 100% rename from examples/type/alias/alias.rs rename to examples/cast/alias/alias.rs diff --git a/examples/type/alias/input.md b/examples/cast/alias/input.md similarity index 100% rename from examples/type/alias/input.md rename to examples/cast/alias/input.md diff --git a/examples/type/cast/cast.rs b/examples/cast/cast.rs similarity index 100% rename from examples/type/cast/cast.rs rename to examples/cast/cast.rs diff --git a/examples/type/inference/inference.rs b/examples/cast/inference/inference.rs similarity index 100% rename from examples/type/inference/inference.rs rename to examples/cast/inference/inference.rs diff --git a/examples/type/inference/input.md b/examples/cast/inference/input.md similarity index 100% rename from examples/type/inference/input.md rename to examples/cast/inference/input.md diff --git a/examples/type/cast/input.md b/examples/cast/input.md similarity index 100% rename from examples/type/cast/input.md rename to examples/cast/input.md diff --git a/examples/type/literals/input.md b/examples/cast/literals/input.md similarity index 100% rename from examples/type/literals/input.md rename to examples/cast/literals/input.md diff --git a/examples/type/literals/literals.rs b/examples/cast/literals/literals.rs similarity index 100% rename from examples/type/literals/literals.rs rename to examples/cast/literals/literals.rs diff --git a/examples/constants/constants.rs b/examples/custom_types/constants/constants.rs similarity index 100% rename from examples/constants/constants.rs rename to examples/custom_types/constants/constants.rs diff --git a/examples/constants/input.md b/examples/custom_types/constants/input.md similarity index 100% rename from examples/constants/input.md rename to examples/custom_types/constants/input.md diff --git a/examples/enum/c_like/c_like.rs b/examples/custom_types/enum/c_like/c_like.rs similarity index 100% rename from examples/enum/c_like/c_like.rs rename to examples/custom_types/enum/c_like/c_like.rs diff --git a/examples/enum/c_like/input.md b/examples/custom_types/enum/c_like/input.md similarity index 100% rename from examples/enum/c_like/input.md rename to examples/custom_types/enum/c_like/input.md diff --git a/examples/enum/enum.rs b/examples/custom_types/enum/enum.rs similarity index 100% rename from examples/enum/enum.rs rename to examples/custom_types/enum/enum.rs diff --git a/examples/enum/input.md b/examples/custom_types/enum/input.md similarity index 100% rename from examples/enum/input.md rename to examples/custom_types/enum/input.md diff --git a/examples/custom_types/input.md b/examples/custom_types/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/custom_types/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/structs/input.md b/examples/custom_types/structs/input.md similarity index 100% rename from examples/structs/input.md rename to examples/custom_types/structs/input.md diff --git a/examples/structs/structs.rs b/examples/custom_types/structs/structs.rs similarity index 100% rename from examples/structs/structs.rs rename to examples/custom_types/structs/structs.rs diff --git a/examples/structs/visibility/input.md b/examples/custom_types/structs/visibility/input.md similarity index 100% rename from examples/structs/visibility/input.md rename to examples/custom_types/structs/visibility/input.md diff --git a/examples/structs/visibility/struct.rs b/examples/custom_types/structs/visibility/struct.rs similarity index 100% rename from examples/structs/visibility/struct.rs rename to examples/custom_types/structs/visibility/struct.rs diff --git a/examples/closures/closures.rs b/examples/fn/closures/closures.rs similarity index 100% rename from examples/closures/closures.rs rename to examples/fn/closures/closures.rs diff --git a/examples/closures/input.md b/examples/fn/closures/input.md similarity index 100% rename from examples/closures/input.md rename to examples/fn/closures/input.md diff --git a/examples/hof/hof.rs b/examples/fn/hof/hof.rs similarity index 100% rename from examples/hof/hof.rs rename to examples/fn/hof/hof.rs diff --git a/examples/hof/input.md b/examples/fn/hof/input.md similarity index 100% rename from examples/hof/input.md rename to examples/fn/hof/input.md diff --git a/examples/methods/input.md b/examples/fn/methods/input.md similarity index 100% rename from examples/methods/input.md rename to examples/fn/methods/input.md diff --git a/examples/methods/methods.rs b/examples/fn/methods/methods.rs similarity index 100% rename from examples/methods/methods.rs rename to examples/fn/methods/methods.rs diff --git a/examples/comment/comment.rs b/examples/hello/comment/comment.rs similarity index 100% rename from examples/comment/comment.rs rename to examples/hello/comment/comment.rs diff --git a/examples/comment/input.md b/examples/hello/comment/input.md similarity index 100% rename from examples/comment/input.md rename to examples/hello/comment/input.md diff --git a/examples/fmt/input.md b/examples/hello/print/fmt/input.md similarity index 100% rename from examples/fmt/input.md rename to examples/hello/print/fmt/input.md diff --git a/examples/fmt/show.rs b/examples/hello/print/fmt/show.rs similarity index 100% rename from examples/fmt/show.rs rename to examples/hello/print/fmt/show.rs diff --git a/examples/print/input.md b/examples/hello/print/input.md similarity index 100% rename from examples/print/input.md rename to examples/hello/print/input.md diff --git a/examples/print/print.rs b/examples/hello/print/print.rs similarity index 100% rename from examples/print/print.rs rename to examples/hello/print/print.rs diff --git a/examples/print/print_debug/debug.rs b/examples/hello/print/print_debug/debug.rs similarity index 100% rename from examples/print/print_debug/debug.rs rename to examples/hello/print/print_debug/debug.rs diff --git a/examples/print/print_debug/input.md b/examples/hello/print/print_debug/input.md similarity index 100% rename from examples/print/print_debug/input.md rename to examples/hello/print/print_debug/input.md diff --git a/examples/print/print_display/display.rs b/examples/hello/print/print_display/display.rs similarity index 100% rename from examples/print/print_display/display.rs rename to examples/hello/print/print_display/display.rs diff --git a/examples/print/print_display/input.md b/examples/hello/print/print_display/input.md similarity index 100% rename from examples/print/print_display/input.md rename to examples/hello/print/print_display/input.md diff --git a/examples/bench/bench.rs b/examples/meta/bench/bench.rs similarity index 100% rename from examples/bench/bench.rs rename to examples/meta/bench/bench.rs diff --git a/examples/bench/input.md b/examples/meta/bench/input.md similarity index 100% rename from examples/bench/input.md rename to examples/meta/bench/input.md diff --git a/examples/comment/doc_comment/doc_comment.rs b/examples/meta/doc_comment/doc_comment.rs similarity index 100% rename from examples/comment/doc_comment/doc_comment.rs rename to examples/meta/doc_comment/doc_comment.rs diff --git a/examples/comment/doc_comment/input.md b/examples/meta/doc_comment/input.md similarity index 100% rename from examples/comment/doc_comment/input.md rename to examples/meta/doc_comment/input.md diff --git a/examples/meta/input.md b/examples/meta/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/meta/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/test/input.md b/examples/meta/test/input.md similarity index 100% rename from examples/test/input.md rename to examples/meta/test/input.md diff --git a/examples/test/unit_test.rs b/examples/meta/test/unit_test.rs similarity index 100% rename from examples/test/unit_test.rs rename to examples/meta/test/unit_test.rs diff --git a/examples/array/array.rs b/examples/primitives/array/array.rs similarity index 100% rename from examples/array/array.rs rename to examples/primitives/array/array.rs diff --git a/examples/array/input.md b/examples/primitives/array/input.md similarity index 100% rename from examples/array/input.md rename to examples/primitives/array/input.md diff --git a/examples/primitives/input.md b/examples/primitives/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/primitives/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/literals/input.md b/examples/primitives/literals/input.md similarity index 100% rename from examples/literals/input.md rename to examples/primitives/literals/input.md diff --git a/examples/literals/literals.rs b/examples/primitives/literals/literals.rs similarity index 100% rename from examples/literals/literals.rs rename to examples/primitives/literals/literals.rs diff --git a/examples/tuples/input.md b/examples/primitives/tuples/input.md similarity index 100% rename from examples/tuples/input.md rename to examples/primitives/tuples/input.md diff --git a/examples/tuples/tuples.rs b/examples/primitives/tuples/tuples.rs similarity index 100% rename from examples/tuples/tuples.rs rename to examples/primitives/tuples/tuples.rs diff --git a/examples/borrow/alias/alias.rs b/examples/scope/borrow/alias/alias.rs similarity index 100% rename from examples/borrow/alias/alias.rs rename to examples/scope/borrow/alias/alias.rs diff --git a/examples/borrow/alias/input.md b/examples/scope/borrow/alias/input.md similarity index 100% rename from examples/borrow/alias/input.md rename to examples/scope/borrow/alias/input.md diff --git a/examples/borrow/borrow.rs b/examples/scope/borrow/borrow.rs similarity index 100% rename from examples/borrow/borrow.rs rename to examples/scope/borrow/borrow.rs diff --git a/examples/borrow/freeze/freeze.rs b/examples/scope/borrow/freeze/freeze.rs similarity index 100% rename from examples/borrow/freeze/freeze.rs rename to examples/scope/borrow/freeze/freeze.rs diff --git a/examples/borrow/freeze/input.md b/examples/scope/borrow/freeze/input.md similarity index 100% rename from examples/borrow/freeze/input.md rename to examples/scope/borrow/freeze/input.md diff --git a/examples/borrow/input.md b/examples/scope/borrow/input.md similarity index 100% rename from examples/borrow/input.md rename to examples/scope/borrow/input.md diff --git a/examples/borrow/mut/input.md b/examples/scope/borrow/mut/input.md similarity index 100% rename from examples/borrow/mut/input.md rename to examples/scope/borrow/mut/input.md diff --git a/examples/borrow/mut/mut.rs b/examples/scope/borrow/mut/mut.rs similarity index 100% rename from examples/borrow/mut/mut.rs rename to examples/scope/borrow/mut/mut.rs diff --git a/examples/borrow/ref/input.md b/examples/scope/borrow/ref/input.md similarity index 100% rename from examples/borrow/ref/input.md rename to examples/scope/borrow/ref/input.md diff --git a/examples/borrow/ref/ref.rs b/examples/scope/borrow/ref/ref.rs similarity index 100% rename from examples/borrow/ref/ref.rs rename to examples/scope/borrow/ref/ref.rs diff --git a/examples/scope/input.md b/examples/scope/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/scope/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/lifetime/borrow/borrow.rs b/examples/scope/lifetime/borrow/borrow.rs similarity index 100% rename from examples/lifetime/borrow/borrow.rs rename to examples/scope/lifetime/borrow/borrow.rs diff --git a/examples/lifetime/borrow/input.md b/examples/scope/lifetime/borrow/input.md similarity index 100% rename from examples/lifetime/borrow/input.md rename to examples/scope/lifetime/borrow/input.md diff --git a/examples/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs similarity index 100% rename from examples/lifetime/explicit/explicit.rs rename to examples/scope/lifetime/explicit/explicit.rs diff --git a/examples/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md similarity index 100% rename from examples/lifetime/explicit/input.md rename to examples/scope/lifetime/explicit/input.md diff --git a/examples/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs similarity index 100% rename from examples/lifetime/fn/fn.rs rename to examples/scope/lifetime/fn/fn.rs diff --git a/examples/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md similarity index 100% rename from examples/lifetime/fn/input.md rename to examples/scope/lifetime/fn/input.md diff --git a/examples/lifetime/input.md b/examples/scope/lifetime/input.md similarity index 100% rename from examples/lifetime/input.md rename to examples/scope/lifetime/input.md diff --git a/examples/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md similarity index 100% rename from examples/lifetime/static_lifetime/input.md rename to examples/scope/lifetime/static_lifetime/input.md diff --git a/examples/lifetime/static_lifetime/static_lifetime.rs b/examples/scope/lifetime/static_lifetime/static_lifetime.rs similarity index 100% rename from examples/lifetime/static_lifetime/static_lifetime.rs rename to examples/scope/lifetime/static_lifetime/static_lifetime.rs diff --git a/examples/lifetime/struct/input.md b/examples/scope/lifetime/struct/input.md similarity index 100% rename from examples/lifetime/struct/input.md rename to examples/scope/lifetime/struct/input.md diff --git a/examples/lifetime/struct/struct.rs b/examples/scope/lifetime/struct/struct.rs similarity index 100% rename from examples/lifetime/struct/struct.rs rename to examples/scope/lifetime/struct/struct.rs diff --git a/examples/move/input.md b/examples/scope/move/input.md similarity index 100% rename from examples/move/input.md rename to examples/scope/move/input.md diff --git a/examples/move/move.rs b/examples/scope/move/move.rs similarity index 100% rename from examples/move/move.rs rename to examples/scope/move/move.rs diff --git a/examples/move/mut/input.md b/examples/scope/move/mut/input.md similarity index 100% rename from examples/move/mut/input.md rename to examples/scope/move/mut/input.md diff --git a/examples/move/mut/mut.rs b/examples/scope/move/mut/mut.rs similarity index 100% rename from examples/move/mut/mut.rs rename to examples/scope/move/mut/mut.rs diff --git a/examples/raii/input.md b/examples/scope/raii/input.md similarity index 100% rename from examples/raii/input.md rename to examples/scope/raii/input.md diff --git a/examples/raii/raii.rs b/examples/scope/raii/raii.rs similarity index 100% rename from examples/raii/raii.rs rename to examples/scope/raii/raii.rs diff --git a/examples/box/box.rs b/examples/std/box/box.rs similarity index 100% rename from examples/box/box.rs rename to examples/std/box/box.rs diff --git a/examples/box/input.md b/examples/std/box/input.md similarity index 100% rename from examples/box/input.md rename to examples/std/box/input.md diff --git a/examples/hash/alt_key_types/alt_key_types.rs b/examples/std/hash/alt_key_types/alt_key_types.rs similarity index 100% rename from examples/hash/alt_key_types/alt_key_types.rs rename to examples/std/hash/alt_key_types/alt_key_types.rs diff --git a/examples/hash/alt_key_types/input.md b/examples/std/hash/alt_key_types/input.md similarity index 100% rename from examples/hash/alt_key_types/input.md rename to examples/std/hash/alt_key_types/input.md diff --git a/examples/hash/hash.rs b/examples/std/hash/hash.rs similarity index 100% rename from examples/hash/hash.rs rename to examples/std/hash/hash.rs diff --git a/examples/hash/hashset/hashset.rs b/examples/std/hash/hashset/hashset.rs similarity index 100% rename from examples/hash/hashset/hashset.rs rename to examples/std/hash/hashset/hashset.rs diff --git a/examples/hash/hashset/input.md b/examples/std/hash/hashset/input.md similarity index 100% rename from examples/hash/hashset/input.md rename to examples/std/hash/hashset/input.md diff --git a/examples/hash/input.md b/examples/std/hash/input.md similarity index 100% rename from examples/hash/input.md rename to examples/std/hash/input.md diff --git a/examples/std/input.md b/examples/std/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/std/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/option/input.md b/examples/std/option/input.md similarity index 100% rename from examples/option/input.md rename to examples/std/option/input.md diff --git a/examples/option/option.rs b/examples/std/option/option.rs similarity index 100% rename from examples/option/option.rs rename to examples/std/option/option.rs diff --git a/examples/panic/input.md b/examples/std/panic/input.md similarity index 100% rename from examples/panic/input.md rename to examples/std/panic/input.md diff --git a/examples/panic/panic.rs b/examples/std/panic/panic.rs similarity index 100% rename from examples/panic/panic.rs rename to examples/std/panic/panic.rs diff --git a/examples/result/input.md b/examples/std/result/input.md similarity index 100% rename from examples/result/input.md rename to examples/std/result/input.md diff --git a/examples/result/result.rs b/examples/std/result/result.rs similarity index 100% rename from examples/result/result.rs rename to examples/std/result/result.rs diff --git a/examples/result/try/input.md b/examples/std/result/try/input.md similarity index 100% rename from examples/result/try/input.md rename to examples/std/result/try/input.md diff --git a/examples/result/try/try.rs b/examples/std/result/try/try.rs similarity index 100% rename from examples/result/try/try.rs rename to examples/std/result/try/try.rs diff --git a/examples/str/input.md b/examples/std/str/input.md similarity index 100% rename from examples/str/input.md rename to examples/std/str/input.md diff --git a/examples/str/str.rs b/examples/std/str/str.rs similarity index 100% rename from examples/str/str.rs rename to examples/std/str/str.rs diff --git a/examples/vec/input.md b/examples/std/vec/input.md similarity index 100% rename from examples/vec/input.md rename to examples/std/vec/input.md diff --git a/examples/vec/vec.rs b/examples/std/vec/vec.rs similarity index 100% rename from examples/vec/vec.rs rename to examples/std/vec/vec.rs diff --git a/examples/arg/args.rs b/examples/std_misc/arg/args.rs similarity index 100% rename from examples/arg/args.rs rename to examples/std_misc/arg/args.rs diff --git a/examples/arg/getopts/echo.rs b/examples/std_misc/arg/getopts/echo.rs similarity index 100% rename from examples/arg/getopts/echo.rs rename to examples/std_misc/arg/getopts/echo.rs diff --git a/examples/arg/getopts/input.md b/examples/std_misc/arg/getopts/input.md similarity index 100% rename from examples/arg/getopts/input.md rename to examples/std_misc/arg/getopts/input.md diff --git a/examples/arg/getopts/test.sh b/examples/std_misc/arg/getopts/test.sh similarity index 100% rename from examples/arg/getopts/test.sh rename to examples/std_misc/arg/getopts/test.sh diff --git a/examples/arg/getopts/testopt.rs b/examples/std_misc/arg/getopts/testopt.rs similarity index 100% rename from examples/arg/getopts/testopt.rs rename to examples/std_misc/arg/getopts/testopt.rs diff --git a/examples/arg/input.md b/examples/std_misc/arg/input.md similarity index 100% rename from examples/arg/input.md rename to examples/std_misc/arg/input.md diff --git a/examples/arg/matching/input.md b/examples/std_misc/arg/matching/input.md similarity index 100% rename from examples/arg/matching/input.md rename to examples/std_misc/arg/matching/input.md diff --git a/examples/arg/matching/match_args.rs b/examples/std_misc/arg/matching/match_args.rs similarity index 100% rename from examples/arg/matching/match_args.rs rename to examples/std_misc/arg/matching/match_args.rs diff --git a/examples/channels/channels.rs b/examples/std_misc/channels/channels.rs similarity index 100% rename from examples/channels/channels.rs rename to examples/std_misc/channels/channels.rs diff --git a/examples/channels/input.md b/examples/std_misc/channels/input.md similarity index 100% rename from examples/channels/input.md rename to examples/std_misc/channels/input.md diff --git a/examples/ffi/ffi.rs b/examples/std_misc/ffi/ffi.rs similarity index 100% rename from examples/ffi/ffi.rs rename to examples/std_misc/ffi/ffi.rs diff --git a/examples/ffi/input.md b/examples/std_misc/ffi/input.md similarity index 100% rename from examples/ffi/input.md rename to examples/std_misc/ffi/input.md diff --git a/examples/ffi/safe.rs b/examples/std_misc/ffi/safe.rs similarity index 100% rename from examples/ffi/safe.rs rename to examples/std_misc/ffi/safe.rs diff --git a/examples/file/create/create.rs b/examples/std_misc/file/create/create.rs similarity index 100% rename from examples/file/create/create.rs rename to examples/std_misc/file/create/create.rs diff --git a/examples/file/create/input.md b/examples/std_misc/file/create/input.md similarity index 100% rename from examples/file/create/input.md rename to examples/std_misc/file/create/input.md diff --git a/examples/file/input.md b/examples/std_misc/file/input.md similarity index 100% rename from examples/file/input.md rename to examples/std_misc/file/input.md diff --git a/examples/file/open/input.md b/examples/std_misc/file/open/input.md similarity index 100% rename from examples/file/open/input.md rename to examples/std_misc/file/open/input.md diff --git a/examples/file/open/open.rs b/examples/std_misc/file/open/open.rs similarity index 100% rename from examples/file/open/open.rs rename to examples/std_misc/file/open/open.rs diff --git a/examples/fs/fs.rs b/examples/std_misc/fs/fs.rs similarity index 100% rename from examples/fs/fs.rs rename to examples/std_misc/fs/fs.rs diff --git a/examples/fs/input.md b/examples/std_misc/fs/input.md similarity index 100% rename from examples/fs/input.md rename to examples/std_misc/fs/input.md diff --git a/examples/std_misc/input.md b/examples/std_misc/input.md new file mode 100644 index 0000000000..20dd49b697 --- /dev/null +++ b/examples/std_misc/input.md @@ -0,0 +1 @@ +Stub diff --git a/examples/path/input.md b/examples/std_misc/path/input.md similarity index 100% rename from examples/path/input.md rename to examples/std_misc/path/input.md diff --git a/examples/path/path.rs b/examples/std_misc/path/path.rs similarity index 100% rename from examples/path/path.rs rename to examples/std_misc/path/path.rs diff --git a/examples/process/input.md b/examples/std_misc/process/input.md similarity index 100% rename from examples/process/input.md rename to examples/std_misc/process/input.md diff --git a/examples/process/pipe/input.md b/examples/std_misc/process/pipe/input.md similarity index 100% rename from examples/process/pipe/input.md rename to examples/std_misc/process/pipe/input.md diff --git a/examples/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs similarity index 100% rename from examples/process/pipe/pipe.rs rename to examples/std_misc/process/pipe/pipe.rs diff --git a/examples/process/process.rs b/examples/std_misc/process/process.rs similarity index 100% rename from examples/process/process.rs rename to examples/std_misc/process/process.rs diff --git a/examples/process/wait/input.md b/examples/std_misc/process/wait/input.md similarity index 100% rename from examples/process/wait/input.md rename to examples/std_misc/process/wait/input.md diff --git a/examples/process/wait/wait.rs b/examples/std_misc/process/wait/wait.rs similarity index 100% rename from examples/process/wait/wait.rs rename to examples/std_misc/process/wait/wait.rs diff --git a/examples/simd/input.md b/examples/std_misc/simd/input.md similarity index 100% rename from examples/simd/input.md rename to examples/std_misc/simd/input.md diff --git a/examples/simd/simd.rs b/examples/std_misc/simd/simd.rs similarity index 100% rename from examples/simd/simd.rs rename to examples/std_misc/simd/simd.rs diff --git a/examples/simd/simd_add.rs b/examples/std_misc/simd/simd_add.rs similarity index 100% rename from examples/simd/simd_add.rs rename to examples/std_misc/simd/simd_add.rs diff --git a/examples/threads/input.md b/examples/std_misc/threads/input.md similarity index 100% rename from examples/threads/input.md rename to examples/std_misc/threads/input.md diff --git a/examples/threads/threads.rs b/examples/std_misc/threads/threads.rs similarity index 100% rename from examples/threads/threads.rs rename to examples/std_misc/threads/threads.rs diff --git a/examples/structure.json b/examples/structure.json index da12543b07..c124796903 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -1,144 +1,155 @@ [ - { "id": "hello", "title": "Hello World", "children": null }, - { "id": "print", "title": "Formatted print", "children": [ - { "id": "print_debug", "title": "Debug", "children": null }, - { "id": "print_display", "title": "Display", "children": null } - ] }, - { "id": "literals", "title": "Literals and operators", "children": null }, - { "id": "variable_bindings", "title": "Variable Bindings", "children": [ - { "id": "mut", "title": "Mutability", "children": null }, - { "id": "scope", "title": "Scope and shadowing", "children": null }, - { "id": "declare", "title": "Declare first", "children": null } - ] }, - { "id": "type", "title": "Types", "children": [ - { "id": "cast", "title": "Casting", "children": null }, - { "id": "literals", "title": "Literals", "children": null }, - { "id": "inference", "title": "Inference", "children": null }, - { "id": "alias", "title": "Alias", "children": null } - ] }, - { "id": "expression", "title": "Expressions", "children": null }, - { "id": "flow_control", "title": "Flow Control", "children": [ - { "id": "if_else", "title": "if/else", "children": null }, - { "id": "loop", "title": "loop", "children": [ - { "id": "nested", "title": "Nesting and labels", "children": null } - ] }, - { "id": "while", "title": "while", "children": null }, - { "id": "for", "title": "for and range", "children": null }, - { "id": "match", "title": "match", "children": [ - { "id": "destructuring", "title": "Destructuring", "children": [ - { "id": "destructure_tuple", "title": "tuples", "children": null }, - { "id": "destructure_enum", "title": "enums", "children": null }, - { "id": "destructure_pointers", "title": "pointers/ref", "children": null }, - { "id": "destructure_structures", "title": "structs", "children": null } - ] }, - { "id": "guard", "title": "Guards", "children": null }, - { "id": "binding", "title": "Binding", "children": null } - ] }, - { "id": "if_let", "title": "if let", "children": null }, - { "id": "while_let", "title": "while let", "children": null } - ] }, - { "id": "fn", "title": "Functions", "children": [ - { "id": "unused", "title": "Unused", "children": null } - ] }, - { "id": "mod", "title": "Modules", "children": [ - { "id": "visibility", "title": "Visibility", "children": null }, - { "id": "use", "title": "The `use` declaration", "children": null }, - { "id": "super", "title": "`super` and `self`", "children": null }, - { "id": "split", "title": "File hierarchy", "children": null } - ] }, - { "id": "crates", "title": "Crates", "children": [ - { "id": "lib", "title": "Library", "children": null }, - { "id": "link", "title": "`extern crate`", "children": null } - ] }, - { "id": "attribute", "title": "Attributes", "children": [ - { "id": "crate", "title": "Crates", "children": null }, - { "id": "cfg", "title": "`cfg`", "children": [ - { "id": "custom", "title": "Custom", "children": null } - ] } - ] }, - { "id": "tuples", "title": "Tuples", "children": null }, - { "id": "structs", "title": "Structures", "children": [ - { "id": "visibility", "title": "Visibility", "children": null } - ] }, - { "id": "generics", "title": "Generics", "children": [ - { "id": "impl", "title": "Implementation", "children": null }, - { "id": "phantom", "title": "Phantom types", "children": [ - { "id": "units", "title": "Unit conversions", "children": null } - ] } - ] }, - { "id": "box", "title": "Box, stack and heap", "children": null }, - { "id": "raii", "title": "RAII", "children": null }, - { "id": "move", "title": "Ownership and moves", "children": [ - { "id": "mut", "title": "Mutability", "children": null } - ] }, - { "id": "borrow", "title": "Borrowing", "children": [ - { "id": "mut", "title": "Mutability", "children": null }, - { "id": "freeze", "title": "Freezing", "children": null }, - { "id": "alias", "title": "Aliasing", "children": null }, - { "id": "ref", "title": "The ref pattern", "children": null } - ] }, - { "id": "lifetime", "title": "Lifetimes", "children": [ - { "id": "borrow", "title": "The borrow checker", "children": null }, - { "id": "fn", "title": "Functions", "children": null }, - { "id": "struct", "title": "Structs", "children": null }, - { "id": "static_lifetime", "title": "static", "children": null } - ] }, - { "id": "constants", "title": "constants", "children": null }, - { "id": "methods", "title": "Methods", "children": null }, - { "id": "enum", "title": "Enums", "children": [ - { "id": "c_like", "title": "C-like", "children": null } - ] }, - { "id": "panic", "title": "`panic!`", "children": null }, - { "id": "option", "title": "`Option`", "children": null }, - { "id": "array", "title": "Arrays and Slices", "children": null }, - { "id": "trait", "title": "Traits", "children": [ - { "id": "derive", "title": "Derive", "children": null } - ] }, - { "id": "ops", "title": "Operator Overloading", "children": null }, - { "id": "bounds", "title": "Bounds", "children": null }, - { "id": "drop", "title": "Drop", "children": null }, - { "id": "iter", "title": "Iterators", "children": null }, - { "id": "closures", "title": "Closures", "children": null }, - { "id": "hof", "title": "Higher Order Functions", "children": null }, - { "id": "vec", "title": "Vectors", "children": null }, - { "id": "str", "title": "Strings", "children": null }, - { "id": "clone", "title": "Clone", "children": null }, - { "id": "threads", "title": "Threads", "children": null }, - { "id": "channels", "title": "Channels", "children": null }, - { "id": "result", "title": "`Result`", "children": [ - { "id": "try", "title": "`try!`", "children": null } - ] }, - { "id": "path", "title": "Path", "children": null }, - { "id": "file", "title": "File I/O", "children": [ - { "id": "open", "title": "`open`", "children": null }, - { "id": "create", "title": "`create`", "children": null } - ] }, - { "id": "process", "title": "Child processes", "children": [ - { "id": "pipe", "title": "Pipes", "children": null }, - { "id": "wait", "title": "Wait", "children": null } - ] }, - { "id": "fs", "title": "Filesystem Operations", "children": null }, - { "id": "bench", "title": "Benchmarking", "children": null }, - { "id": "comment", "title": "Comments", "children": [ - { "id": "doc_comment", "title": "Doc Comments", "children": null } - ] }, - { "id": "ffi", "title": "Foreign Function Interface", "children": null }, - { "id": "macros", "title": "macro_rules!", "children": [ - { "id": "designators", "title": "Designators", "children": null }, - { "id": "overload", "title": "Overload", "children": null }, - { "id": "repeat", "title": "Repeat", "children": null }, - { "id": "dry", "title": "DRY", "children": null } - ] }, - { "id": "arg", "title": "Program arguments", "children": [ - { "id": "matching", "title": "Argument parsing", "children": null }, - { "id": "getopts", "title": "`getopts`", "children": null } - ] }, - { "id": "simd", "title": "SIMD", "children": null }, - { "id": "test", "title": "Testing", "children": null }, - { "id": "unsafe", "title": "Unsafe operations", "children": null }, - { "id": "fmt", "title": "Formatting", "children": null }, - { "id": "hash", "title": "HashMap", "children": [ - { "id": "alt_key_types", "title": "Alternate/custom key types", "children": null}, - { "id": "hashset", "title": "HashSet", "children": null } - ] } + { "id": "hello", "title": "Hello World", "children": [ + { "id": "comment", "title": "Comments", "children": null }, + { "id": "print", "title": "Formatted print", "children": [ + { "id": "print_debug", "title": "Debug", "children": null }, + { "id": "print_display", "title": "Display", "children": null }, + { "id": "fmt", "title": "Formatting", "children": null } + ] } + ] }, + { "id": "primitives", "title": "Primitives", "children": [ + { "id": "literals", "title": "Literals and operators", "children": null }, + { "id": "tuples", "title": "Tuples", "children": null }, + { "id": "array", "title": "Arrays and Slices", "children": null } + ] }, + { "id": "custom_types", "title": "Custom types", "children": [ + { "id": "structs", "title": "Structures", "children": [ + { "id": "visibility", "title": "Visibility", "children": null } + ] }, + { "id": "enum", "title": "Enums", "children": [ + { "id": "c_like", "title": "C-like", "children": null } + ] }, + { "id": "constants", "title": "constants", "children": null } + ] }, + { "id": "variable_bindings", "title": "Variable Bindings", "children": [ + { "id": "mut", "title": "Mutability", "children": null }, + { "id": "scope", "title": "Scope and shadowing", "children": null }, + { "id": "declare", "title": "Declare first", "children": null } + ] }, + { "id": "cast", "title": "Casting", "children": [ + { "id": "literals", "title": "Literals", "children": null }, + { "id": "inference", "title": "Inference", "children": null }, + { "id": "alias", "title": "Alias", "children": null } + ] }, + { "id": "expression", "title": "Expressions", "children": null }, + { "id": "flow_control", "title": "Flow Control", "children": [ + { "id": "if_else", "title": "if/else", "children": null }, + { "id": "loop", "title": "loop", "children": [ + { "id": "nested", "title": "Nesting and labels", "children": null } + ] }, + { "id": "while", "title": "while", "children": null }, + { "id": "for", "title": "for and range", "children": null }, + { "id": "match", "title": "match", "children": [ + { "id": "destructuring", "title": "Destructuring", "children": [ + { "id": "destructure_tuple", "title": "tuples", "children": null }, + { "id": "destructure_enum", "title": "enums", "children": null }, + { "id": "destructure_pointers", "title": "pointers/ref", "children": null }, + { "id": "destructure_structures", "title": "structs", "children": null } + ] }, + { "id": "guard", "title": "Guards", "children": null }, + { "id": "binding", "title": "Binding", "children": null } + ] }, + { "id": "if_let", "title": "if let", "children": null }, + { "id": "while_let", "title": "while let", "children": null } + ] }, + { "id": "fn", "title": "Functions", "children": [ + { "id": "unused", "title": "Unused", "children": null }, + { "id": "methods", "title": "Methods", "children": null }, + { "id": "closures", "title": "Closures", "children": null }, + { "id": "hof", "title": "Higher Order Functions", "children": null } + ] }, + { "id": "macros", "title": "macro_rules!", "children": [ + { "id": "designators", "title": "Designators", "children": null }, + { "id": "overload", "title": "Overload", "children": null }, + { "id": "repeat", "title": "Repeat", "children": null }, + { "id": "dry", "title": "DRY", "children": null } + ] }, + { "id": "mod", "title": "Modules", "children": [ + { "id": "visibility", "title": "Visibility", "children": null }, + { "id": "use", "title": "The `use` declaration", "children": null }, + { "id": "super", "title": "`super` and `self`", "children": null }, + { "id": "split", "title": "File hierarchy", "children": null } + ] }, + { "id": "crates", "title": "Crates", "children": [ + { "id": "lib", "title": "Library", "children": null }, + { "id": "link", "title": "`extern crate`", "children": null } + ] }, + { "id": "attribute", "title": "Attributes", "children": [ + { "id": "crate", "title": "Crates", "children": null }, + { "id": "cfg", "title": "`cfg`", "children": [ + { "id": "custom", "title": "Custom", "children": null } + ] } + ] }, + { "id": "generics", "title": "Generics", "children": [ + { "id": "impl", "title": "Implementation", "children": null }, + { "id": "phantom", "title": "Phantom types", "children": [ + { "id": "units", "title": "Unit conversions", "children": null } + ] } + ] }, + { "id": "scope", "title": "Scoping rules", "children": [ + { "id": "raii", "title": "RAII", "children": null }, + { "id": "move", "title": "Ownership and moves", "children": [ + { "id": "mut", "title": "Mutability", "children": null } + ] }, + { "id": "borrow", "title": "Borrowing", "children": [ + { "id": "mut", "title": "Mutability", "children": null }, + { "id": "freeze", "title": "Freezing", "children": null }, + { "id": "alias", "title": "Aliasing", "children": null }, + { "id": "ref", "title": "The ref pattern", "children": null } + ] }, + { "id": "lifetime", "title": "Lifetimes", "children": [ + { "id": "borrow", "title": "The borrow checker", "children": null }, + { "id": "fn", "title": "Functions", "children": null }, + { "id": "struct", "title": "Structs", "children": null }, + { "id": "static_lifetime", "title": "static", "children": null } + ] } + ] }, + { "id": "trait", "title": "Traits", "children": [ + { "id": "derive", "title": "Derive", "children": null }, + { "id": "ops", "title": "Operator Overloading", "children": null }, + { "id": "bounds", "title": "Bounds", "children": null }, + { "id": "drop", "title": "Drop", "children": null }, + { "id": "iter", "title": "Iterators", "children": null }, + { "id": "clone", "title": "Clone", "children": null } + ] }, + { "id": "std", "title": "Std library types", "children": [ + { "id": "box", "title": "Box, stack and heap", "children": null }, + { "id": "vec", "title": "Vectors", "children": null }, + { "id": "str", "title": "Strings", "children": null }, + { "id": "option", "title": "`Option`", "children": null }, + { "id": "result", "title": "`Result`", "children": [ + { "id": "try", "title": "`try!`", "children": null } + ] }, + { "id": "panic", "title": "`panic!`", "children": null }, + { "id": "hash", "title": "HashMap", "children": [ + { "id": "alt_key_types", "title": "Alternate/custom key types", "children": null}, + { "id": "hashset", "title": "HashSet", "children": null } + ] } + ] }, + { "id": "std_misc", "title": "Std misc", "children": [ + { "id": "threads", "title": "Threads", "children": null }, + { "id": "channels", "title": "Channels", "children": null }, + { "id": "path", "title": "Path", "children": null }, + { "id": "file", "title": "File I/O", "children": [ + { "id": "open", "title": "`open`", "children": null }, + { "id": "create", "title": "`create`", "children": null } + ] }, + { "id": "process", "title": "Child processes", "children": [ + { "id": "pipe", "title": "Pipes", "children": null }, + { "id": "wait", "title": "Wait", "children": null } + ] }, + { "id": "fs", "title": "Filesystem Operations", "children": null }, + { "id": "arg", "title": "Program arguments", "children": [ + { "id": "matching", "title": "Argument parsing", "children": null }, + { "id": "getopts", "title": "`getopts`", "children": null } + ] }, + { "id": "ffi", "title": "Foreign Function Interface", "children": null }, + { "id": "simd", "title": "SIMD", "children": null } + ] }, + { "id": "meta", "title": "Meta", "children": [ + { "id": "doc_comment", "title": "Documentation", "children": null }, + { "id": "test", "title": "Testing", "children": null }, + { "id": "bench", "title": "Benchmarking", "children": null } + ] }, + { "id": "unsafe", "title": "Unsafe operations", "children": null } ] diff --git a/examples/bounds/bounds.rs b/examples/trait/bounds/bounds.rs similarity index 100% rename from examples/bounds/bounds.rs rename to examples/trait/bounds/bounds.rs diff --git a/examples/bounds/input.md b/examples/trait/bounds/input.md similarity index 100% rename from examples/bounds/input.md rename to examples/trait/bounds/input.md diff --git a/examples/clone/clone.rs b/examples/trait/clone/clone.rs similarity index 100% rename from examples/clone/clone.rs rename to examples/trait/clone/clone.rs diff --git a/examples/clone/input.md b/examples/trait/clone/input.md similarity index 100% rename from examples/clone/input.md rename to examples/trait/clone/input.md diff --git a/examples/drop/drop.rs b/examples/trait/drop/drop.rs similarity index 100% rename from examples/drop/drop.rs rename to examples/trait/drop/drop.rs diff --git a/examples/drop/input.md b/examples/trait/drop/input.md similarity index 100% rename from examples/drop/input.md rename to examples/trait/drop/input.md diff --git a/examples/iter/input.md b/examples/trait/iter/input.md similarity index 100% rename from examples/iter/input.md rename to examples/trait/iter/input.md diff --git a/examples/iter/iter.rs b/examples/trait/iter/iter.rs similarity index 100% rename from examples/iter/iter.rs rename to examples/trait/iter/iter.rs diff --git a/examples/ops/input.md b/examples/trait/ops/input.md similarity index 100% rename from examples/ops/input.md rename to examples/trait/ops/input.md diff --git a/examples/ops/operator.rs b/examples/trait/ops/operator.rs similarity index 100% rename from examples/ops/operator.rs rename to examples/trait/ops/operator.rs From f2b59d8f4a56388a57d40aaca5f9f19d2c025e85 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 30 Apr 2015 16:02:13 -0400 Subject: [PATCH 0233/1122] Rename doc_comment to doc --- examples/meta/{doc_comment/doc_comment.rs => doc/doc.rs} | 0 examples/meta/{doc_comment => doc}/input.md | 2 +- examples/structure.json | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename examples/meta/{doc_comment/doc_comment.rs => doc/doc.rs} (100%) rename examples/meta/{doc_comment => doc}/input.md (94%) diff --git a/examples/meta/doc_comment/doc_comment.rs b/examples/meta/doc/doc.rs similarity index 100% rename from examples/meta/doc_comment/doc_comment.rs rename to examples/meta/doc/doc.rs diff --git a/examples/meta/doc_comment/input.md b/examples/meta/doc/input.md similarity index 94% rename from examples/meta/doc_comment/input.md rename to examples/meta/doc/input.md index 721deb52fc..31dc60057c 100644 --- a/examples/meta/doc_comment/input.md +++ b/examples/meta/doc/input.md @@ -2,7 +2,7 @@ Doc comments are very useful for big projects that require documentation. When running [Rustdoc][1], these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown][2]. -{doc_comment.play} +{doc.play} [1]: https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc.md [2]: https://en.wikipedia.org/wiki/Markdown diff --git a/examples/structure.json b/examples/structure.json index c124796903..96784d807b 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -147,7 +147,7 @@ { "id": "simd", "title": "SIMD", "children": null } ] }, { "id": "meta", "title": "Meta", "children": [ - { "id": "doc_comment", "title": "Documentation", "children": null }, + { "id": "doc", "title": "Documentation", "children": null }, { "id": "test", "title": "Testing", "children": null }, { "id": "bench", "title": "Benchmarking", "children": null } ] }, From 3cdce73af8a1cb37c99cf9ad078c6ce8fe3e7698 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 15:00:15 -0400 Subject: [PATCH 0234/1122] Update comments section --- examples/hello/comment/comment.rs | 16 ++++++++++++++-- examples/hello/comment/input.md | 21 ++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/examples/hello/comment/comment.rs b/examples/hello/comment/comment.rs index 4f291b934f..beebd8a393 100644 --- a/examples/hello/comment/comment.rs +++ b/examples/hello/comment/comment.rs @@ -8,7 +8,19 @@ fn main() { // Run it. See? Now try deleting the two slashes, and run it again. /* - * This is another type of comment, the block comment. It's not used - * in Rust very often, and is against the Rust Style Guide. + * This is another type of comment, the block comment. In general, + * the line comment is the recommended comment style however the + * block comment is extremely useful for debugging */ + + /* + Note, the previous column of `*` was entirely for style. There's + no actual need for it. + */ + + // Observe how block comments allow easy expression manipulation + // which line comments do not. Deleting the comment deliminators + // will change the result: + let x = 5 + /* 90 + */ 5; + println!("Is `x` 10 or 100? x = {}", x); } diff --git a/examples/hello/comment/input.md b/examples/hello/comment/input.md index 273ef7734b..4afd7cf471 100644 --- a/examples/hello/comment/input.md +++ b/examples/hello/comment/input.md @@ -1,11 +1,18 @@ -Comments are a necessary part of any serious program, and most non-serious -programs as well. +Any program requires comments and indeed Rust supports +a few different varieties: -There are two ways to write comments in Rust, "block" (`/**/`) and "line" -(`//`). However, the [Rust style guide][2] recommends only using the second. -There are also "Doc" comments, used for documentation. +* *Regular comments* which are ignored by the compiler: + - `// Line comments which go to the end of the line.` + - `/* Block comments which go to the closing deliminator. */` +* *Doc comments* which are parsed into HTML library +[documentation][docs]: + - `/// Generate library docs for the following item.` + - `!// Generate library docs for the enclosing item.` {comment.play} -[1]: https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc.md -[2]: https://aturon.github.io/style/comments.html +### See also: + +[Library documentation][docs] + +[docs]: /meta/doc.html From e1bc65b6d2c753cdf2a2bd705c11938c491afeb8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 15:48:42 -0400 Subject: [PATCH 0235/1122] Fix broken links --- examples/cast/alias/input.md | 3 ++- examples/cast/literals/input.md | 2 +- examples/custom_types/constants/input.md | 2 +- examples/flow_control/if_let/input.md | 4 ++-- .../match/destructuring/destructure_enum/input.md | 2 +- .../destructuring/destructure_structures/input.md | 2 +- .../match/destructuring/destructure_tuple/input.md | 2 +- examples/flow_control/match/guard/input.md | 2 +- examples/flow_control/while_let/input.md | 4 ++-- examples/hello/print/input.md | 8 ++++---- examples/hello/print/print_debug/input.md | 4 ++-- examples/hello/print/print_display/input.md | 10 +++++----- examples/meta/test/input.md | 6 +++--- examples/primitives/literals/input.md | 13 +++++++------ examples/scope/lifetime/borrow/input.md | 4 ++-- examples/scope/lifetime/static_lifetime/input.md | 2 +- 16 files changed, 36 insertions(+), 34 deletions(-) diff --git a/examples/cast/alias/input.md b/examples/cast/alias/input.md index 58b2e56c73..d3328238d6 100644 --- a/examples/cast/alias/input.md +++ b/examples/cast/alias/input.md @@ -8,4 +8,5 @@ The main use of aliases is to reduce typing; for example the `IoResult` type is an alias for the `Result` type. ### See also: -[attributes](./attribute.html) + +[Attributes](/attribute.html) diff --git a/examples/cast/literals/input.md b/examples/cast/literals/input.md index 5b02c05840..26c74d8b38 100644 --- a/examples/cast/literals/input.md +++ b/examples/cast/literals/input.md @@ -19,6 +19,6 @@ yet, here's a brief explanation for the impatient readers: is defined in the `std` *crate*. For more details, see [modules][mod] and [crates][crate]. -[borrow]: /borrow.html +[borrow]: /scope/borrow.html [mod]: /mod.html [crate]: /crates.html diff --git a/examples/custom_types/constants/input.md b/examples/custom_types/constants/input.md index 5a46644a88..d45882506e 100644 --- a/examples/custom_types/constants/input.md +++ b/examples/custom_types/constants/input.md @@ -19,4 +19,4 @@ hides the distinction. https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md), [`'static` lifetime][static] -[static]: ./lifetime/static_lifetime.html +[static]: /scope/lifetime/static_lifetime.html diff --git a/examples/flow_control/if_let/input.md b/examples/flow_control/if_let/input.md index 3e793edb7e..b053555cc7 100644 --- a/examples/flow_control/if_let/input.md +++ b/examples/flow_control/if_let/input.md @@ -26,6 +26,6 @@ failure options to be specified: [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] -[enum]: /enum.html +[enum]: /custom_types/enum.html [if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 -[option]: /option.html +[option]: /std/option.html diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index 83658513f6..f3cd111785 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -6,6 +6,6 @@ An `enum` is destructured similarly: [`#[allow(...)]`][allow], [`enum`][enum], and [`#[derive(...)]`][derive] -[enum]: /enum.html +[enum]: /custom_types/enum.html [derive]: /trait/derive.html [allow]: /fn/unused.html diff --git a/examples/flow_control/match/destructuring/destructure_structures/input.md b/examples/flow_control/match/destructuring/destructure_structures/input.md index d393ee3190..1f1459dea5 100644 --- a/examples/flow_control/match/destructuring/destructure_structures/input.md +++ b/examples/flow_control/match/destructuring/destructure_structures/input.md @@ -4,4 +4,4 @@ Similarly, a `struct` can be destructured as shown: ### See also: -[Structs](/structs.html), [The ref pattern](/borrow/ref.html) +[Structs](/custom_types/structs.html), [The ref pattern](/scope/borrow/ref.html) diff --git a/examples/flow_control/match/destructuring/destructure_tuple/input.md b/examples/flow_control/match/destructuring/destructure_tuple/input.md index 2394fe6bb5..5512b8fe69 100644 --- a/examples/flow_control/match/destructuring/destructure_tuple/input.md +++ b/examples/flow_control/match/destructuring/destructure_tuple/input.md @@ -4,4 +4,4 @@ Tuples can be destructured in a `match` as follows: ### See also: -[Tuples](/tuples.html) +[Tuples](/primitives/tuples.html) diff --git a/examples/flow_control/match/guard/input.md b/examples/flow_control/match/guard/input.md index a9b0987a78..9da083d2d1 100644 --- a/examples/flow_control/match/guard/input.md +++ b/examples/flow_control/match/guard/input.md @@ -4,4 +4,4 @@ A `match` *guard* can be added to filter the arm. ### See also: -[Tuples](/tuples.html) +[Tuples](/primitives/tuples.html) diff --git a/examples/flow_control/while_let/input.md b/examples/flow_control/while_let/input.md index 925f888f53..01cfe6cc3f 100644 --- a/examples/flow_control/while_let/input.md +++ b/examples/flow_control/while_let/input.md @@ -34,6 +34,6 @@ loop { [`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] -[enum]: /enum.html -[option]: /option.html +[enum]: /custom_types/enum.html +[option]: /std/option.html [while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index 3357f4a22a..0d98399e2c 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -26,7 +26,7 @@ for these types. To print text for custom types, more steps are required. and [`trait`s][traits] [fmt]: http://doc.rust-lang.org/std/fmt/ -[macros]: ./macros.html -[string]: ./str.html -[structs]: ./structs.html -[traits]: ./trait.html +[macros]: /macros.html +[string]: /std/str.html +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/examples/hello/print/print_debug/input.md b/examples/hello/print/print_debug/input.md index 5cc3218b4a..b4dc3ff0ee 100644 --- a/examples/hello/print/print_debug/input.md +++ b/examples/hello/print/print_debug/input.md @@ -31,7 +31,7 @@ elegance. Manually implementing `fmt::Display` will fix that. and [`struct`][structs] [attributes]: http://doc.rust-lang.org/reference.html#attributes -[derive]: ./trait/derive.html +[derive]: /trait/derive.html [fmt]: http://doc.rust-lang.org/std/fmt/ -[structs]: ./structs.html +[structs]: /custom_types/structs.html diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 37529944ca..07c5210de9 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -51,9 +51,9 @@ each requires it's own implementation. This is detailed further in [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] -[derive]: ./trait/derive.html +[derive]: /trait/derive.html [fmt]: http://doc.rust-lang.org/std/fmt/ -[macros]: ./macros.html -[structs]: ./structs.html -[traits]: ./trait.html -[use]: ./mod/use.html +[macros]: /macros.html +[structs]: /custom_types/structs.html +[traits]: /trait.html +[use]: /mod/use.html diff --git a/examples/meta/test/input.md b/examples/meta/test/input.md index 556fb18d80..31237d6c9d 100644 --- a/examples/meta/test/input.md +++ b/examples/meta/test/input.md @@ -31,6 +31,6 @@ If you see this, the tests were not compiled nor ran! [attributes][attributes], [conditional compilation][cfg], and [`mod`][mod]. -[attributes]: ./attribute.html -[cfg]: ./attribute/cfg.html -[mod]: ./mod.html +[attributes]: /attribute.html +[cfg]: /attribute/cfg.html +[mod]: /mod.html diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index 1278564aca..8066b7267c 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -8,10 +8,11 @@ Underscores can be inserted in numeric literals to improve readability, e.g. `1_000` is the same as `1000`, and `0.000_001` is the same as `0.000001`. We need to tell the compiler the type of the literals we use. For now, -we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, -and the `i32` suffix to indicate that it's a signed 32-bit integer. We'll cover the type -system in [another chapter][type], and give more details about type -annotating literals in [their own section][type-literal]. +we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit +integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. +We'll cover the type system in [another chapter][primitives], and give more +details about type annotating literals in +[their own section][primitive_literals]. The operators available and their precedence are similar to other [C-like languages][op-prec]. @@ -19,5 +20,5 @@ The operators available and their precedence are similar to other {literals.play} [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages -[type]: /type.html -[type-literal]: /type/literals.html +[primitives]: /primitives.html +[primitive_literals]: /primitives/literals.html diff --git a/examples/scope/lifetime/borrow/input.md b/examples/scope/lifetime/borrow/input.md index 2014b1dd5d..d61e1fe336 100644 --- a/examples/scope/lifetime/borrow/input.md +++ b/examples/scope/lifetime/borrow/input.md @@ -49,5 +49,5 @@ are the cases where explicit lifetimes are required: * [Functions that return references][lifetime] * [Structs that hold references][structs] -[lifetime]: /lifetime/fn.html -[structs]: /lifetime/struct.html +[lifetime]: /scope/lifetime/fn.html +[structs]: /scope/lifetime/struct.html diff --git a/examples/scope/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md index 4f1cfb4701..ac0e12198e 100644 --- a/examples/scope/lifetime/static_lifetime/input.md +++ b/examples/scope/lifetime/static_lifetime/input.md @@ -10,4 +10,4 @@ program. There are two ways to make a variable with `'static` lifetime: [`'static` constants][static_const] -[static_const]: ./constants.html +[static_const]: /custom_types/constants.html From b3d62dcf5c95a37cbed03cbb625d0bbe094c574d Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 21:50:47 -0400 Subject: [PATCH 0236/1122] Add testcase explaining fmt::Display for vec --- examples/hello/print/print_display/input.md | 6 ++-- .../print_display/testcase_list/input.md | 29 +++++++++++++++++++ .../testcase_list/testcase_list.rs | 29 +++++++++++++++++++ examples/structure.json | 4 ++- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 examples/hello/print/print_display/testcase_list/input.md create mode 100644 examples/hello/print/print_display/testcase_list/testcase_list.rs diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 07c5210de9..1d6325a8b6 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -16,8 +16,10 @@ struct Structure(i32); impl fmt::Display for Structure { // This trait requires `fmt` with this exact signature. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Print strictly the first element in the structure. `write!` uses - // syntax which is very similar to `println!`. + // Write strictly the first element into the supplied output + // stream: `f`. Returns `fmt::Result` which indicates whether the + // operation succeeded or failed. Note that `write!` uses syntax which + // is very similar to `println!`. write!(f, "{}", self.0) } } diff --git a/examples/hello/print/print_display/testcase_list/input.md b/examples/hello/print/print_display/testcase_list/input.md new file mode 100644 index 0000000000..784db00599 --- /dev/null +++ b/examples/hello/print/print_display/testcase_list/input.md @@ -0,0 +1,29 @@ +Implementing `fmt::Display` for a structure where the elements must each be +handled sequentially is tricky. The problem is that each `write!` generates a +`fmt::Result`. Proper handling of this requires dealing with *all* the +results. Rust provides the `try!` macro for exactly this purpose. + +Using `try!` on `write!` looks like this: + +```rust +// Try `write!` to see if it errors. If it errors, return +// the error. Otherwise continue. +try!(write!(f, "{}", value)); +``` + +With `try!` available, implementing `fmt::Display` for a `Vec` is +straightforward: + +{testcase_list.play} + +### See also: + +[`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], +[`try!`][try], and [`vec!`][vec] + +[for]: /flow_control/for.html +[result]: /std/result.html +[ref]: /scope/borrow/ref.html +[struct]: /custom_types/structs.html +[try]: /std/result/try.html +[vec]: /std/vec.html diff --git a/examples/hello/print/print_display/testcase_list/testcase_list.rs b/examples/hello/print/print_display/testcase_list/testcase_list.rs new file mode 100644 index 0000000000..79d2b707cf --- /dev/null +++ b/examples/hello/print/print_display/testcase_list/testcase_list.rs @@ -0,0 +1,29 @@ +use std::fmt; // Import the `fmt` module. + +// Define a structure named `List` containing a `Vec`. +struct List(Vec); + +impl fmt::Display for List { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Dereference `self` and create a reference to `vec` + // via destructuring. + let List(ref vec) = *self; + let len = vec.len(); // Save the vector length in `len`. + + // Iterate over `vec` in `v` while enumerating the iteration + // count in `count`. + for (count, v) in vec.iter().enumerate() { + // For every element except the last, format `write!` + // with a comma. Use `try!` to return on errors. + if count < len - 1 { try!(write!(f, "{}, ", v)) } + } + + // `write!` the last value without special formatting. + write!(f, "{}", vec[len-1]) + } +} + +fn main() { + let v = List(vec![1, 2, 3]); + println!("{}", v); +} diff --git a/examples/structure.json b/examples/structure.json index 96784d807b..ed99dfb93d 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -3,7 +3,9 @@ { "id": "comment", "title": "Comments", "children": null }, { "id": "print", "title": "Formatted print", "children": [ { "id": "print_debug", "title": "Debug", "children": null }, - { "id": "print_display", "title": "Display", "children": null }, + { "id": "print_display", "title": "Display", "children": [ + { "id": "testcase_list", "title": "Testcase: List", "children": null } + ] }, { "id": "fmt", "title": "Formatting", "children": null } ] } ] }, From f907782ab812e267c90b36627799e6326d349850 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 23:04:35 -0400 Subject: [PATCH 0237/1122] Move type to primitives and update it. Move type safety --- examples/primitives/input.md | 23 ++++++++++++++++++++++- examples/primitives/primitives.rs | 16 ++++++++++++++++ examples/type/input.md | 15 --------------- examples/type/type.rs | 10 ---------- examples/variable_bindings/input.md | 5 +++++ 5 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 examples/primitives/primitives.rs delete mode 100644 examples/type/input.md delete mode 100644 examples/type/type.rs diff --git a/examples/primitives/input.md b/examples/primitives/input.md index 20dd49b697..becf7e4c02 100644 --- a/examples/primitives/input.md +++ b/examples/primitives/input.md @@ -1 +1,22 @@ -Stub +Rust provides access to a wide variety of `primitives`. A sample includes: + +* signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) +* unsigned integers: `u8`, `u16`, `u32`, `u64` and `usize` (pointer size) +* floating point: `f32`, `f64` +* `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) +* `bool` either `true` or `false` +* and the unit type `()`, whose only value is also `()` +* arrays like `[1, 2, 3]` +* tuples like `(1, true)` + +Variables can be always be *type annotated*. Numbers may additionally be +annotated via a *suffix* or by *default*. Integers default to `i32` and +floats to `f64`. + +{primitives.play} + +### See also: + +[the `std` library][std] + +[std]: http://doc.rust-lang.org/std/ diff --git a/examples/primitives/primitives.rs b/examples/primitives/primitives.rs new file mode 100644 index 0000000000..918b9f7d53 --- /dev/null +++ b/examples/primitives/primitives.rs @@ -0,0 +1,16 @@ +fn main() { + // Variables can be type annotated. + let logical: bool = true; + + let a_float: f64 = 1.0; // Regular annotation + let an_integer = 5i32; // Suffix annotation + + // Or a default will be used. + let default_float = 3.0; // `f64` + let default_integer = 7; // `i32` + + let mut mutable = 12; // Mutable `i32`. + + // Error! The type of a variable can't be changed + mutable = true; +} diff --git a/examples/type/input.md b/examples/type/input.md deleted file mode 100644 index c26df5cb06..0000000000 --- a/examples/type/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Rust provides type safety via static typing. Variable bindings can be type -annotated when declared. However, in most cases, the compiler will be able to -infer the type of the variable from the context, heavily reducing the -annotation burden. - -{type.play} - -This is a summary of the primitive types in Rust: - -* signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) -* unsigned integers: `u8`, `u16`, `u32`, `u64` and `usize` (pointer size) -* floating point: `f32`, `f64` -* `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) -* `bool` either `true` or `false` -* and the unit type `()`, whose only value is also `()` diff --git a/examples/type/type.rs b/examples/type/type.rs deleted file mode 100644 index 8eea3e6de5..0000000000 --- a/examples/type/type.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - // Type annotated variable - let a_float: f64 = 1.0; - - // This variable is an `i32` - let mut an_integer = 5i32; - - // Error! The type of a variable can't be changed - an_integer = true; -} diff --git a/examples/variable_bindings/input.md b/examples/variable_bindings/input.md index f191c25c40..160d49ba48 100644 --- a/examples/variable_bindings/input.md +++ b/examples/variable_bindings/input.md @@ -1,3 +1,8 @@ +Rust provides type safety via static typing. Variable bindings can be type +annotated when declared. However, in most cases, the compiler will be able +to infer the type of the variable from the context, heavily reducing the +annotation burden. + Values (like literals) can be bound to variables, using the `let` binding. {variable_bindings.play} From 1d87e93d4032563356aa2ed75c99fe54b0012447 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 23:07:12 -0400 Subject: [PATCH 0238/1122] Unstub some topics --- examples/custom_types/input.md | 7 ++++++- examples/meta/input.md | 11 ++++++++++- examples/scope/input.md | 3 ++- examples/std/input.md | 16 +++++++++++++++- examples/std_misc/input.md | 16 +++++++++++++++- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/examples/custom_types/input.md b/examples/custom_types/input.md index 20dd49b697..c31c15fd3c 100644 --- a/examples/custom_types/input.md +++ b/examples/custom_types/input.md @@ -1 +1,6 @@ -Stub +Rust custom data types are formed mainly through the two keywords: + +* `struct`: define a structure +* `enum`: define an enumeration + +Constants can also be created via the `const` and `static` keywords. diff --git a/examples/meta/input.md b/examples/meta/input.md index 20dd49b697..c9c048eb9f 100644 --- a/examples/meta/input.md +++ b/examples/meta/input.md @@ -1 +1,10 @@ -Stub +Some topics aren't exactly relevant to how you program but provide you +tooling or infrastructure support which just makes things better for +everyone. These topics include: + +* Documentation: Generate library documentation for users via the included +`rustdoc`. +* Testing: Create testsuites for libraries to give confidence that your +library does exactly what it's supposed to. +* Benchmarking: Create benchmarks for functionality to be confident that +they run quickly. diff --git a/examples/scope/input.md b/examples/scope/input.md index 20dd49b697..7f75ed1775 100644 --- a/examples/scope/input.md +++ b/examples/scope/input.md @@ -1 +1,2 @@ -Stub +Scoping plays an important part which relates directly to how ownership, +borrowing, and lifetimes play out. diff --git a/examples/std/input.md b/examples/std/input.md index 20dd49b697..bcc934871e 100644 --- a/examples/std/input.md +++ b/examples/std/input.md @@ -1 +1,15 @@ -Stub +The `std` library provides many custom types which expands drastically on +the `primitives`. Some of these include: + +* growable `String`s like: `"hello world"` +* growable vectors: `[1, 2, 3]` +* optional types: `Option` +* error handling types: `Result` +* heap allocated pointers: `Box` + +### See also: + +[primitives][primitives] and [the std library][std] + +[primitives]: /primitives.html +[std]: http://doc.rust-lang.org/std/ diff --git a/examples/std_misc/input.md b/examples/std_misc/input.md index 20dd49b697..37eadeead6 100644 --- a/examples/std_misc/input.md +++ b/examples/std_misc/input.md @@ -1 +1,15 @@ -Stub +Many other types are provided by the std library to support +things such as: + +* Threads +* Channels +* File I/O + +These expand beyond what the [primitives][primitives] provide. + +### See also: + +[primitives][primitives] and [the std library][std] + +[primitives]: /primitives.html +[std]: http://doc.rust-lang.org/std/ From ae829f9f907957a010c52ae5631c4211d97cad6b Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 23:30:26 -0400 Subject: [PATCH 0239/1122] Update whitelist --- Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index bee633080a..af10291f6f 100644 --- a/Makefile +++ b/Makefile @@ -4,21 +4,21 @@ STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) # ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ - examples/borrow/borrow.rs \ - examples/borrow/freeze/freeze.rs \ - examples/borrow/mut/mut.rs \ - examples/bounds/bounds.rs \ - examples/constants/constants.rs \ + examples/scope/borrow/borrow.rs \ + examples/scope/borrow/freeze/freeze.rs \ + examples/scope/borrow/mut/mut.rs \ + examples/trait/bounds/bounds.rs \ + examples/custom_types/constants/constants.rs \ examples/crates/link/executable.rs \ - examples/lifetime/borrow/borrow.rs \ + examples/scope/lifetime/borrow/borrow.rs \ examples/mod/mod.rs \ - examples/print/print.rs \ - examples/type/cast/cast.rs \ - examples/type/type.rs \ + examples/hello/print/print.rs \ + examples/cast/cast.rs \ + examples/primitives/primitives.rs \ examples/variable_bindings/scope/scope.rs \ examples/variable_bindings/mut/mut.rs \ examples/variable_bindings/declare/declare.rs \ - examples/vec/vec.rs + examples/std/vec/vec.rs srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) From 8ebc3781b227a43f5e0c817a49dc39ef66668a5c Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 1 May 2015 23:32:26 -0400 Subject: [PATCH 0240/1122] Fix broken links --- examples/flow_control/match/struct/input.md | 4 +++- examples/trait/derive/input.md | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/flow_control/match/struct/input.md b/examples/flow_control/match/struct/input.md index e3c274dae3..c65ae271d8 100644 --- a/examples/flow_control/match/struct/input.md +++ b/examples/flow_control/match/struct/input.md @@ -4,4 +4,6 @@ A `struct` can be destructured with pattern matching. ### See also: -[Structs](/structs.html) +[`struct`][structs] + +[structs]: /structs.html diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index f668d29ab0..9a428b15e2 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -23,8 +23,6 @@ This is a list of the "derivable" traits: to create an empty instance of a data type. * `Zero`, to create a zero instance of a numeric data type. -* [`FromPrimitive`][from-primitive], - to create an instance from a numeric primitive. * [`Debug`][debug], to format a value using the `{:?}` formatter. @@ -38,5 +36,4 @@ This is a list of the "derivable" traits: [clone]: http://doc.rust-lang.org/std/clone/trait.Clone.html [hash]: http://doc.rust-lang.org/std/hash/trait.Hash.html [default]: http://doc.rust-lang.org/std/default/trait.Default.html -[from-primitive]: http://doc.rust-lang.org/std/num/trait.FromPrimitive.html [debug]: http://doc.rust-lang.org/std/fmt/trait.Debug.html From 155e93f138a98b6932b85b984df11dd438365fa0 Mon Sep 17 00:00:00 2001 From: Robert Marcano Date: Sat, 2 May 2015 19:16:17 -0430 Subject: [PATCH 0241/1122] Fix format traits based on API docs See Formatting traits at https://doc.rust-lang.org/std/fmt/ --- examples/hello/print/fmt/input.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/examples/hello/print/fmt/input.md b/examples/hello/print/fmt/input.md index 44d7ced399..d2c03fd481 100644 --- a/examples/hello/print/fmt/input.md +++ b/examples/hello/print/fmt/input.md @@ -16,20 +16,14 @@ handles cases where the argument type is left unspecified: `{}` for instance. Here's the full list of formatting traits and their respective argument types: -* *unspecified* -> `Debug` -* `d` and `i` -> `Signed` -* `u` -> `Unsigned` -* `b` -> `Bool` -* `c` -> `Char` +* *unspecified* -> `Display` +* `?` -> `Debug` * `o` -> `Octal` * `x` -> `LowerHex` * `X` -> `UpperHex` -* `s` -> `String` * `p` -> `Pointer` -* `t` -> `Binary` -* `f` -> `Float` +* `b` -> `Binary` * `e` -> `LowerExp` * `E` -> `UpperExp` -* `?` -> `Poly` [deadbeef]: https://en.wikipedia.org/wiki/Deadbeef#Magic_debug_values From d7a3a4cc7a80e80aca35361e0ad1847b5ef18c17 Mon Sep 17 00:00:00 2001 From: Jyrki Puttonen Date: Sun, 3 May 2015 17:41:19 +0300 Subject: [PATCH 0242/1122] RGB(i32, i32, i32) does not require name The RGB(i32, i32, i32) does not require name, so fix the comment. --- .../flow_control/match/destructuring/destructure_enum/enum.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs index 8e9e841790..f92baf493e 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/enum.rs +++ b/examples/flow_control/match/destructuring/destructure_enum/enum.rs @@ -8,7 +8,7 @@ enum Color { Red, Blue, Green, - // This requires 3 `i32`s and a name. + // This requires 3 `i32`s. RGB(i32, i32, i32), } From 14d8b486a8b73e6d5eefb7a3ec89cb9380619f6d Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 3 May 2015 15:52:17 -0400 Subject: [PATCH 0243/1122] Be more clear about enum variants name --- .../destructuring/destructure_enum/enum.rs | 22 ++++++++++++++----- .../destructuring/destructure_enum/input.md | 8 ++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs index f92baf493e..c917840440 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/enum.rs +++ b/examples/flow_control/match/destructuring/destructure_enum/enum.rs @@ -8,8 +8,12 @@ enum Color { Red, Blue, Green, - // This requires 3 `i32`s. - RGB(i32, i32, i32), + // These likewise tie `u32` tuples to different names: color models. + RGB(u32, u32, u32), + HSV(u32, u32, u32), + HSL(u32, u32, u32), + CMY(u32, u32, u32), + CMYK(u32, u32, u32, u32), } fn main() { @@ -22,9 +26,17 @@ fn main() { Color::Red => println!("The color is Red!"), Color::Blue => println!("The color is Blue!"), Color::Green => println!("The color is Green!"), - Color::RGB(r, g, b) => { - println!("Red: {:?}, green: {:?}, and blue: {:?}!", r, g, b); - }, + Color::RGB(r, g, b) => + println!("Red: {}, green: {}, and blue: {}!", r, g, b), + Color::HSV(h, s, v) => + println!("Hue: {}, saturation: {}, value: {}!", h, s, v), + Color::HSL(h, s, l) => + println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l), + Color::CMY(c, m, y) => + println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y), + Color::CMYK(c, m, y, k) => + println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!", + c, m, y, k), // Don't need another arm because all variants have been examined } } diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index f3cd111785..b39e0bc8cf 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -4,8 +4,10 @@ An `enum` is destructured similarly: ### See also: -[`#[allow(...)]`][allow], [`enum`][enum], and [`#[derive(...)]`][derive] +[`#[allow(...)]`][allow], [color models][color_models], [`enum`][enum], +and [`#[derive(...)]`][derive] -[enum]: /custom_types/enum.html -[derive]: /trait/derive.html [allow]: /fn/unused.html +[color_models]: http://en.wikipedia.org/wiki/Color_model +[derive]: /trait/derive.html +[enum]: /custom_types/enum.html From d8b4c5a527d744119b91faa6056fe90e384fde9d Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 6 May 2015 03:19:39 -0400 Subject: [PATCH 0244/1122] Always say yes to rustup interactive questions --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3d87af3af6..185a056f94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: true install: - - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly + - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly --yes script: - rustc --version From 6b257280d460e9775d4e745b3741c6241ea687c4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 6 May 2015 16:30:19 -0400 Subject: [PATCH 0245/1122] Fix warning soft_link warning. Remove unnecessary Paths --- examples/std_misc/fs/fs.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/examples/std_misc/fs/fs.rs b/examples/std_misc/fs/fs.rs index 128b717521..66f6b32c5e 100644 --- a/examples/std_misc/fs/fs.rs +++ b/examples/std_misc/fs/fs.rs @@ -4,6 +4,7 @@ use std::fs; use std::fs::{File, OpenOptions}; use std::io; use std::io::prelude::*; +use std::os::unix; use std::path::Path; // A simple implementation of `% cat path` @@ -34,7 +35,7 @@ fn touch(path: &Path) -> io::Result<()> { fn main() { println!("`mkdir a`"); // Create a directory, returns `io::Result<()>` - match fs::create_dir(&Path::new("a")) { + match fs::create_dir("a") { Err(why) => println!("! {:?}", why.kind()), Ok(_) => {}, } @@ -47,7 +48,7 @@ fn main() { println!("`mkdir -p a/c/d`"); // Recursively create a directory, returns `io::Result<()>` - fs::create_dir_all(&Path::new("a/c/d")).unwrap_or_else(|why| { + fs::create_dir_all("a/c/d").unwrap_or_else(|why| { println!("! {:?}", why.kind()); }); @@ -58,10 +59,11 @@ fn main() { println!("`ln -s ../b.txt a/c/b.txt`"); // Create a symbolic link, returns `io::Result<()>` - fs::soft_link(&Path::new("../b.txt"), - &Path::new("a/c/b.txt")).unwrap_or_else(|why| { + if cfg!(target_family = "unix") { + unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| { println!("! {:?}", why.kind()); - }); + }); + } println!("`cat a/c/b.txt`"); match cat(&Path::new("a/c/b.txt")) { @@ -71,7 +73,7 @@ fn main() { println!("`ls a`"); // Read the contents of a directory, returns `io::Result>` - match fs::read_dir(&Path::new("a")) { + match fs::read_dir("a") { Err(why) => println!("! {:?}", why.kind()), Ok(paths) => for path in paths { println!("> {:?}", path.unwrap().path()); @@ -81,7 +83,7 @@ fn main() { println!("`walk a`"); // Recursively walk over the contents of a directory, returns // `Directories`, which implements the `Iterator trait - match fs::walk_dir(&Path::new("a")) { + match fs::walk_dir("a") { Err(why) => println!("! {:?}", why.kind()), Ok(paths) => for path in paths { println!("> {:?}", path.unwrap().path()); @@ -90,13 +92,13 @@ fn main() { println!("`rm a/c/e.txt`"); // Remove a file, returns `io::Result<()>` - fs::remove_file(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { + fs::remove_file("a/c/e.txt").unwrap_or_else(|why| { println!("! {:?}", why.kind()); }); println!("`rmdir a/c/d`"); // Remove an empty directory, returns `io::Result<()>` - fs::remove_dir(&Path::new("a/c/d")).unwrap_or_else(|why| { + fs::remove_dir("a/c/d").unwrap_or_else(|why| { println!("! {:?}", why.kind()); }); } From c9253a05023060965a1f03653d729965aa6f36dd Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 6 May 2015 16:35:00 -0400 Subject: [PATCH 0246/1122] Add cfg! to fs example --- examples/std_misc/fs/input.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/std_misc/fs/input.md b/examples/std_misc/fs/input.md index 162d3ce765..8435bacaac 100644 --- a/examples/std_misc/fs/input.md +++ b/examples/std_misc/fs/input.md @@ -39,3 +39,10 @@ a 1 directory, 2 files ``` + +### See also: + +[`cfg!`][cfg] + +[cfg]: /attribute/cfg.html + From bcb173f5ef39851fd1f01ac0ccc9ca00b76c6066 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:20:41 -0400 Subject: [PATCH 0247/1122] Expand generics to include sections on: * generic functions * generic traits * expressing bounds - testcase covering empty bounds * expressing multiple bounds * explain where clauses * explaining associated types - how to constrain associated types - added a testcase implementing an `Add` trait --- .../assoc_types/constrain/constrain.rs | 37 ++++++++++++++ .../generics/assoc_types/constrain/input.md | 30 +++++++++++ examples/generics/assoc_types/input.md | 17 +++++++ .../assoc_types/testcase_add/input.md | 4 ++ .../assoc_types/testcase_add/testcase.rs | 51 +++++++++++++++++++ .../generics/assoc_types/the_problem/input.md | 22 ++++++++ .../assoc_types/the_problem/problem.rs | 44 ++++++++++++++++ .../assoc_types/the_solution/input.md | 35 +++++++++++++ .../assoc_types/the_solution/solution.rs | 50 ++++++++++++++++++ examples/generics/bounds/bounds.rs | 38 ++++++++++++++ examples/generics/bounds/input.md | 36 +++++++++++++ .../generics/bounds/testcase_empty/empty.rs | 27 ++++++++++ .../generics/bounds/testcase_empty/input.md | 13 +++++ examples/generics/gen_fn/fn.rs | 34 +++++++++++++ examples/generics/gen_fn/input.md | 16 ++++++ examples/generics/gen_trait/input.md | 12 +++++ examples/generics/gen_trait/trait.rs | 30 +++++++++++ examples/generics/generics.rs | 44 +++++++--------- examples/generics/impl/input.md | 18 ++++--- examples/generics/input.md | 25 ++++++--- examples/generics/multi_bounds/input.md | 11 ++++ examples/generics/multi_bounds/multi.rs | 23 +++++++++ examples/generics/where/input.md | 27 ++++++++++ examples/generics/where/where.rs | 23 +++++++++ examples/structure.json | 13 +++++ 25 files changed, 642 insertions(+), 38 deletions(-) create mode 100644 examples/generics/assoc_types/constrain/constrain.rs create mode 100644 examples/generics/assoc_types/constrain/input.md create mode 100644 examples/generics/assoc_types/input.md create mode 100644 examples/generics/assoc_types/testcase_add/input.md create mode 100644 examples/generics/assoc_types/testcase_add/testcase.rs create mode 100644 examples/generics/assoc_types/the_problem/input.md create mode 100644 examples/generics/assoc_types/the_problem/problem.rs create mode 100644 examples/generics/assoc_types/the_solution/input.md create mode 100644 examples/generics/assoc_types/the_solution/solution.rs create mode 100644 examples/generics/bounds/bounds.rs create mode 100644 examples/generics/bounds/input.md create mode 100644 examples/generics/bounds/testcase_empty/empty.rs create mode 100644 examples/generics/bounds/testcase_empty/input.md create mode 100644 examples/generics/gen_fn/fn.rs create mode 100644 examples/generics/gen_fn/input.md create mode 100644 examples/generics/gen_trait/input.md create mode 100644 examples/generics/gen_trait/trait.rs create mode 100644 examples/generics/multi_bounds/input.md create mode 100644 examples/generics/multi_bounds/multi.rs create mode 100644 examples/generics/where/input.md create mode 100644 examples/generics/where/where.rs diff --git a/examples/generics/assoc_types/constrain/constrain.rs b/examples/generics/assoc_types/constrain/constrain.rs new file mode 100644 index 0000000000..b855f698ea --- /dev/null +++ b/examples/generics/assoc_types/constrain/constrain.rs @@ -0,0 +1,37 @@ +use std::fmt::Display; + +struct Container(T); + +// Trait returns whatever is inside. +trait Contains { + type A; + // Return inner element. + fn inner(&self) -> Self::A; +} + +impl Contains for Container { + type A = T; + + // Clone to prevent move. + fn inner(&self) -> Self::A { self.0.clone() } +} + +// Bounds on associated types. +fn printer(c: C) where + C: Contains, + C::A: Display { + println!("{}", c.inner()); +} + +// The assignment shorthand: +fn num_small(c: C) -> i32 where + C: Contains { + c.inner() +} + + +fn main() { + printer(Container(17i32)); + + println!("{}", num_small(Container(4i32))); +} diff --git a/examples/generics/assoc_types/constrain/input.md b/examples/generics/assoc_types/constrain/input.md new file mode 100644 index 0000000000..a4f3065ff2 --- /dev/null +++ b/examples/generics/assoc_types/constrain/input.md @@ -0,0 +1,30 @@ +Functionality depending on associated types may require applying bounds. + +```rust +trait Contains { + type A; + ... +} + +// Bounds are applied through the container: `C::A: Trait`. +fn apply_bounds(c: C) where + C: Contains, + C::A: Display { ... } + +// Caveat: This hasn't been implemented yet and doesn't work. +// +// Equality is also through the container: `C::A = type`. +fn apply_eq(c: C) where + C: Contains, + C::A = i32 { ... } + +// Note: There is no bounds shorthand. Only equality. +// +// An equality shorthand is provided: +fn apply_eq_shorthand(c: C) where + C: Contains { ... } +``` + +The full example: + +{constrain.play} diff --git a/examples/generics/assoc_types/input.md b/examples/generics/assoc_types/input.md new file mode 100644 index 0000000000..4e6e05cb17 --- /dev/null +++ b/examples/generics/assoc_types/input.md @@ -0,0 +1,17 @@ +Associated Items is an extension to `trait` generics which adds a different +feel and style to generics. It encompasses a set of rules pertaining to +[`item`s][items] of various types. The main one under under consideration here +is Associated Types. Associated Types adds one new concept: + +* `trait`s can now internally define a `type` via the keyword `type`. This is +called an *output* type. + +The result is much simpler usage patterns when the `trait` is generic over +containers. + +### See also: + +[RFC]( +https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md +) +[items]: http://doc.rust-lang.org/reference.html#items diff --git a/examples/generics/assoc_types/testcase_add/input.md b/examples/generics/assoc_types/testcase_add/input.md new file mode 100644 index 0000000000..0d63e1838d --- /dev/null +++ b/examples/generics/assoc_types/testcase_add/input.md @@ -0,0 +1,4 @@ +Here is a possible implementation of an `Add` trait using associated +types. + +{testcase.play} diff --git a/examples/generics/assoc_types/testcase_add/testcase.rs b/examples/generics/assoc_types/testcase_add/testcase.rs new file mode 100644 index 0000000000..f0b2a5fda2 --- /dev/null +++ b/examples/generics/assoc_types/testcase_add/testcase.rs @@ -0,0 +1,51 @@ +#[derive(Debug)] +struct I32(i32); +#[derive(Debug)] +struct I64(i64); + +// `Self + Rhs = Sum`: Once the types for `Self` and `Rhs` are +// determined, `Sum` is known. +trait Add { + type Sum; + + // Use `&self` and `&Rhs` so no changes are made to the originals. + // The return shouldn't be a reference. + fn add(&self, rhs: &Rhs) -> Self::Sum; +} + +impl Add for I32 { + type Sum = I32; + + fn add(&self, rhs: &I32) -> Self::Sum { I32(self.0 + rhs.0) } +} + +impl Add for I32 { + type Sum = I64; + + fn add(&self, rhs: &I64) -> Self::Sum { I64(self.0 as i64 + rhs.0) } +} + +impl Add for I64 { + type Sum = I64; + + fn add(&self, rhs: &I32) -> Self::Sum { I64(self.0 + rhs.0 as i64) } +} + +impl Add for I64 { + type Sum = I64; + + fn add(&self, rhs: &I64) -> Self::Sum { I64(self.0 + rhs.0) } +} + + +fn main() { + let i = I32(12); + let j = I64(9); + + println!("{:?} + {:?} = {:?}", &i, &i, i.add(&i)); + + println!("{:?} + {:?} = {:?}", &i, &j, i.add(&j)); + println!("{:?} + {:?} = {:?}", &j, &i, j.add(&i)); + + println!("{:?} + {:?} = {:?}", &j, &j, j.add(&j)); +} diff --git a/examples/generics/assoc_types/the_problem/input.md b/examples/generics/assoc_types/the_problem/input.md new file mode 100644 index 0000000000..3f72793931 --- /dev/null +++ b/examples/generics/assoc_types/the_problem/input.md @@ -0,0 +1,22 @@ +`trait`s generic over container types have strict type specification +requirements. Users of the `trait`s *must* specify all generic types, even +irrelevant ones. + +Specifically, examine the `Contains` `trait` and the `difference()` function +which utilizes it. The fact that `Contains` is generic immediately forces +users of the `trait` regardless of need to explicitly state *all* the +`trait`'s generic types. + +{problem.play} + +The problem is we require a way to express that `A` and `B` are determined +by the *input* `C`. Having to express them as *input* parameters is just +hindering. Associated types provides exactly that capability. + +### See also: + +[`struct`s][structs], and [`trait`s][traits] + + +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/examples/generics/assoc_types/the_problem/problem.rs b/examples/generics/assoc_types/the_problem/problem.rs new file mode 100644 index 0000000000..09a25bd04d --- /dev/null +++ b/examples/generics/assoc_types/the_problem/problem.rs @@ -0,0 +1,44 @@ +struct Container(i32, i32); + +// A trait which will check to see if 2 items are stored inside of container. +// Also retrieves first or last value. +trait Contains { + fn contains(&self, &A, &B) -> bool; // Explicitly requires `A` and `B`. + fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`. + fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`. +} + +impl Contains for Container { + // True if the numbers stored are equal. + fn contains(&self, number: &i32, digit: &i32) -> bool { + (&self.0 == number) && (&self.1 == digit) + } + + // Grab the first number. + fn first(&self) -> i32 { self.0 } + + // Grab the last number. + fn last(&self) -> i32 { self.1 } +} + +// `C` contains `A` and `B`. In light of that, having to express `A` and +// `B` again is a nuisance. +fn difference(container: &C) -> i32 where + C: Contains { + container.last() - container.first() +} + +fn main() { + let number = 3; + let digit = 10; + + let container = Container(number, digit); + + println!("Does container contain {} and {}: {}", + &number, &digit, + container.contains(&number, &digit)); + println!("First number: {}", container.first()); + println!("Last number: {}", container.last()); + + println!("The difference is: {}", difference(&container)); +} diff --git a/examples/generics/assoc_types/the_solution/input.md b/examples/generics/assoc_types/the_solution/input.md new file mode 100644 index 0000000000..6a073c6aff --- /dev/null +++ b/examples/generics/assoc_types/the_solution/input.md @@ -0,0 +1,35 @@ +Associated types moves the internal types locally into the trait to be +called *output* types. This shields future users of the trait from the +substantial boilerplate previously required. For example: + +```rust +// The original trait +trait Contains { + fn contains(&self, &A, &B) -> bool; +} + +// Updated. Now `A` and `B` are defined in the trait via the `type` keyword +// (Note: `type` is this context is different from `type` when used for +// aliases). +trait Contains { + type A; + type B; + + // Updated syntax to refer to these new types generically. + fn contains(&self, &Self::A, &Self::B) -> bool; +} +``` + +Users of the `trait` reap the greatest benefits though. This generic function +doesn't need to express `A` or `B` at all: + +```rust +// The original +fn difference(container: &C) -> i32 where + C: Contains { ... } + +// The updated now no longer has `A` and `B` as requirements. +fn difference(container: &C) -> i32 { ... } +``` + +{solution.play} diff --git a/examples/generics/assoc_types/the_solution/solution.rs b/examples/generics/assoc_types/the_solution/solution.rs new file mode 100644 index 0000000000..c685a92aa9 --- /dev/null +++ b/examples/generics/assoc_types/the_solution/solution.rs @@ -0,0 +1,50 @@ +struct Container(i32, i32); + +// A trait which will check to see if 2 items are stored inside of container. +// Also retrieves first or last value. +trait Contains { + // Define generic types here which methods will be able utilize. + type A; + type B; + + fn contains(&self, &Self::A, &Self::B) -> bool; + fn first(&self) -> i32; + fn last(&self) -> i32; +} + +impl Contains for Container { + // Specify what types `A` and `B` are. If the `input` type + // is `Container(i32, i32)`, the `output` types are determined + // as `i32` and `i32`. + type A = i32; + type B = i32; + + // `&Self::A` and `&self::B` are also valid here. + fn contains(&self, number: &i32, digit: &i32) -> bool { + (&self.0 == number) && (&self.1 == digit) + } + // Grab the first number. + fn first(&self) -> i32 { self.0 } + + // Grab the last number. + fn last(&self) -> i32 { self.1 } +} + +fn difference(container: &C) -> i32 { + container.last() - container.first() +} + +fn main() { + let number = 3; + let digit = 10; + + let container = Container(number, digit); + + println!("Does container contain {} and {}: {}", + &number, &digit, + container.contains(&number, &digit)); + println!("First number: {}", container.first()); + println!("Last number: {}", container.last()); + + println!("The difference is: {}", difference(&container)); +} diff --git a/examples/generics/bounds/bounds.rs b/examples/generics/bounds/bounds.rs new file mode 100644 index 0000000000..d85cab323c --- /dev/null +++ b/examples/generics/bounds/bounds.rs @@ -0,0 +1,38 @@ +// A trait which implements the print marker: `{:?}`. +use std::fmt::Debug; + +trait HasArea { + fn area(&self) -> f64; +} + +impl HasArea for Rectangle { + fn area(&self) -> f64 { self.length * self.height } +} + +#[derive(Debug)] +struct Rectangle { length: f64, height: f64 } +#[allow(dead_code)] +struct Triangle { length: f64, height: f64 } + +// The generic `T` must implement `Debug`. So regardless +// of the type, this will work properly. +fn print_debug(t: &T) { + println!("{:?}", t); +} + +// `T` must implement `HasArea`. Any function which meets +// the bound can access `HasArea`'s function `area`. +fn area(t: &T) -> f64 { t.area() } + +fn main() { + let rectangle = Rectangle { length: 3.0, height: 4.0 }; + let _triangle = Triangle { length: 3.0, height: 4.0 }; + + print_debug(&rectangle); + println!("Area: {}", area(&rectangle)); + + //print_debug(&_triangle); + //println!("Area: {}", area(&_triangle)); + // ^ TODO: Try uncommenting these. + // | Error: Does not implement either `Debug` or `HasArea`. +} diff --git a/examples/generics/bounds/input.md b/examples/generics/bounds/input.md new file mode 100644 index 0000000000..8c4952426d --- /dev/null +++ b/examples/generics/bounds/input.md @@ -0,0 +1,36 @@ +When working with generics, the types often must use traits as *bounds* to +stipulate what functionality a type implements. For example, the following +example uses the trait `Display` to print and so it requires `T` to be bound +by `Display`; that is, `T` *must* implement `Display`. + +```rust +// This function reads: `printer` takes generic type `T` which +// must implement trait `Display`. +fn printer(t: T) { + println!("{}", t); +} +``` + +One consequence of this is it allows generic instances to access the methods +of the traits specified in the bounds. For example: + +{bounds.play} + +Bounding also restricts the generic from being specialized to +types that do *not* conform to the bounds. That is: + +```rust +struct S(T); + +// Error! `Vec` does not implement `Display`. This +// specialization will fail. +let s = S(vec![1]); +``` + +### See also: + +[`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] + +[fmt]: /hello/print.html +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/examples/generics/bounds/testcase_empty/empty.rs b/examples/generics/bounds/testcase_empty/empty.rs new file mode 100644 index 0000000000..c19dbdbd36 --- /dev/null +++ b/examples/generics/bounds/testcase_empty/empty.rs @@ -0,0 +1,27 @@ +struct Cardinal; +struct BlueJay; +struct Turkey; + +trait Red {} +trait Blue {} + +impl Red for Cardinal {} +impl Blue for BlueJay {} + +// These functions are only valid for types which implement these +// traits. The fact that the traits are empty is irrelevant. +fn red(_: &T) -> &'static str { "red" } +fn blue(_: &T) -> &'static str { "blue" } + +fn main() { + let cardinal = Cardinal; + let blue_jay = BlueJay; + let _turkey = Turkey; + + // `red()` won't work on a blue jay nor vice versa + // because of the bounds. + println!("A cardinal is {}", red(&cardinal)); + println!("A blue jay is {}", blue(&blue_jay)); + //println!("A turkey is {}", red(&_turkey)); + // ^ TODO: Try uncommenting this line. +} diff --git a/examples/generics/bounds/testcase_empty/input.md b/examples/generics/bounds/testcase_empty/input.md new file mode 100644 index 0000000000..ecab81825a --- /dev/null +++ b/examples/generics/bounds/testcase_empty/input.md @@ -0,0 +1,13 @@ +A consequence of how bounds work is that even if a `trait` doesn't +include any functionality, you can still use it as a bound. `Eq` and +`Ord` are examples of such `trait`s from the `std` library. + +{empty.play} + +### See also: + +[`std::cmp::Eq`][eq], [`std::cmp::Ord`s][ord], and [`trait`s][traits] + +[eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html +[ord]: http://doc.rust-lang.org/std/cmp/trait.Ord.html +[traits]: /trait.html diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs new file mode 100644 index 0000000000..4d54f1d473 --- /dev/null +++ b/examples/generics/gen_fn/fn.rs @@ -0,0 +1,34 @@ +struct T; // Concrete type. +struct S(T); // Concrete type. +struct SGen(T); // Generic type. + +// These functions all take ownership of the variable passed into +// them and immediately go out of scope freeing the variable. +// +// This has no preceding `` so this must be a regular function. +fn die_regular(s: S) {} + +// Has a `` but it isn't preceded by `` to make it generic. +// This is a regular function which takes `SGen` which has +// been specialized to type `T` defined at the top. +fn die_generic_specialized_t(s: SGen) {} + +// A regular function taking `SGen` specialized to `i32`. +fn die_generic_specialized_i32(s: SGen) {} + +// `` is preceded by ``. This function is generic over `T`. +fn die_generic(s: SGen) {} + +fn main() { + // Use the regular functions like normal + die_regular(S(T)); // Concrete type. + die_generic_specialized_t(SGen(T)); // Specialized generic type. + die_generic_specialized_i32(SGen(6)); // Specialized generic type. + + // Explicitly specialize `die_generic()` to `char`. + die_generic::(SGen('a')); + + // Implicitly specialize `die_generic()` to `char`. + die_generic(SGen('c')); +} + diff --git a/examples/generics/gen_fn/input.md b/examples/generics/gen_fn/input.md new file mode 100644 index 0000000000..c66a323e1f --- /dev/null +++ b/examples/generics/gen_fn/input.md @@ -0,0 +1,16 @@ +The same set of rules can be applied to functions: a type `T` is only +generic if it has been preceded by ``. This allows functions to have +a variety of forms, some which may have surprising consequences. + +Generic function usage also sometimes requires explicitly specializing +the call. An explicitly specialized function call looks like: +`fun::()`. + +{fn.play} + +### See also: + +[functions][fn] and [`struct`s][structs] + +[fn]: /fn.html +[structs]: /custom_types/structs.html diff --git a/examples/generics/gen_trait/input.md b/examples/generics/gen_trait/input.md new file mode 100644 index 0000000000..d77dee3135 --- /dev/null +++ b/examples/generics/gen_trait/input.md @@ -0,0 +1,12 @@ +Of course `trait`s can also be generic. Here is a trait which reimplements +the `Drop` `trait` as a generic method which `drop`s itself and an input. + +{trait.play} + +### See also: + +[`Drop`][drop], [`struct`s][structs], and [`trait`s][traits] + +[drop]: http://doc.rust-lang.org/std/ops/trait.Drop.html +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/examples/generics/gen_trait/trait.rs b/examples/generics/gen_trait/trait.rs new file mode 100644 index 0000000000..7f154bc072 --- /dev/null +++ b/examples/generics/gen_trait/trait.rs @@ -0,0 +1,30 @@ +// Non-copyable types. +struct Empty; +struct Null; + +// A trait generic over `T`. +trait DoubleDrop { + // It defines a method on the caller type which takes an + // additional single parameter and does nothing with it. + fn double_drop(self, _: T); +} + +// Implement `DoubleDrop` for any generic parameter `T` and +// caller `U`. +impl DoubleDrop for U { + // This method takes ownership of both passed arguments, + // deallocating both. + fn double_drop(self, _: T) {} +} + +fn main() { + let empty = Empty; + let null = Null; + + // Deallocate `empty` and `null`. + empty.double_drop(null); + + //empty; + //null; + // ^ TODO: Try uncommenting these lines. +} diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index 8db13eb22f..2c1f632c24 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -1,33 +1,25 @@ -// A generic struct -struct Pair { - first: T, - second: T, -} - -// A generic function -fn swap(pair: Pair) -> Pair { - let Pair { first, second } = pair; +// A concrete type `T`. +struct T; - Pair { first: second, second: first } -} +// The first use of `T` was not preceded by `` so `Single` must +// be a concrete type. `T` is defined at the top. +struct Single(T); +// ^ Here is `Single`s first use of the type `T`. -// Reimplementing a 2-element tuple as a tuple struct -struct Tuple2(T, U); +// The first use of `T` is preceded by ``. `SingleGen` must be +// generic and has not yet been specialized. `T` could be anything +// including `T` at the top. +struct SingleGen(T); +// Instantiating the types can be implicit or explicit. fn main() { - // Explicitly specialize `Pair` - let pair_of_chars: Pair = Pair { first: 'a', second: 'b' }; + // Regular `Single`. + let _s = Single(T); - // Implicitly specialize `Pair` - let pair_of_ints = Pair { first: 1i32, second: 2 }; + // `SingleGen` explicity specialized. + let _char: SingleGen = SingleGen('a'); - // Explicitly specialize `Tuple2` - let _tuple: Tuple2 = Tuple2('R', 2); - - // Explicitly specialize `swap` - let _swapped_pair_of_chars = swap::(pair_of_chars); - - // Implicitly specialize `swap` - let _swapped_pair_of_ints = swap(pair_of_ints); + // `SingleGen`s implicitly specialized. + let _t = SingleGen(T); // Uses `T` at top. + let _i32 = SingleGen(6); // Uses `i32`. } - diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 0544b6650e..3382094733 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -1,5 +1,4 @@ -Implementations can also be made generic. Generally, `impl` is followed by -the type ``, although it is not a strict requirement. +Similar to functions, implementations require care to remain generic. ```rust struct S; // A null struct @@ -13,11 +12,18 @@ impl GenericTup {} // Specialize to `S` defined above impl GenericTup {} ``` +Note: Rust does not *currently* allow overlap between implementations. The +3 separate implementations of `GenericTup` above cannot coexist. There are +[plans][specialization_plans] to fix this though. + {impl.play} -###See also: +### See also: + +[functions returning references][fn], [`impl`][methods], and [`struct`][structs] -[impl](http://rustbyexample.com/methods.html), -[struct](http://rustbyexample.com/structs.html), and -[functions returning references](http://rustbyexample.com/lifetime/fn.html), +[fn]: /scope/lifetime/fn.html +[methods]: /fn/methods.html +[specialization_plans]: http://blog.rust-lang.org/2015/05/11/traits.html#the-future +[structs]: /custom_types/structs.html diff --git a/examples/generics/input.md b/examples/generics/input.md index 57f3c9b95e..cff71e8e9d 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -1,9 +1,22 @@ -Generic structs can be declared to hold generic types, and generic functions -can be declared to take generic types as arguments. +Generics is the topic of generalizing types and functionality to be more broad +than one specific type. This is extremely useful in reducing code duplication +in many ways. We will find though that being generic will involve taking +great care to actually specify what types a generic type is actually valid +over. This will require a rather involving syntax, though it seems +straightforward at first. -Generics must be specialized when used, but, because of type inference, -annotation is usually not required. When that's not the case, structs can be -specialized via type annotation, and functions can be specialized passing the -generic arguments using this syntax `::`. +A type is specified as generic by ``. There are 2 basic rules +regarding this which are applied *at* the types first use: + +* Any type previously and locally specified to be generic is generic. +* Everything else is concrete (non-generic). + +These rules play out like this: {generics.play} + +### See also: + +[`struct`s][structs] + +[structs]: /custom_types/structs.html diff --git a/examples/generics/multi_bounds/input.md b/examples/generics/multi_bounds/input.md new file mode 100644 index 0000000000..a628ef1943 --- /dev/null +++ b/examples/generics/multi_bounds/input.md @@ -0,0 +1,11 @@ +Multiple bounds can be applied with a `+`. Like normal, different types are +separated with `,`. + +{multi.play} + +### See also: + +[`std::fmt`][fmt] and [`trait`s][traits] + +[fmt]: /hello/print.html +[traits]: /trait.html diff --git a/examples/generics/multi_bounds/multi.rs b/examples/generics/multi_bounds/multi.rs new file mode 100644 index 0000000000..0db273d34f --- /dev/null +++ b/examples/generics/multi_bounds/multi.rs @@ -0,0 +1,23 @@ +use std::fmt::{Debug, Display}; + +fn compare_prints(t: &T) { + println!("Debug: `{:?}`", t); + println!("Display: `{}`", t); +} + +fn compare_types(t: &T, u: &U) { + println!("t: `{:?}", t); + println!("u: `{:?}", u); +} + +fn main() { + let string = "words"; + let array = [1, 2, 3]; + let vec = vec![1, 2, 3]; + + compare_prints(&string); + //compare_prints(&array); + // TODO ^ Try uncommenting this. + + compare_types(&array, &vec); +} diff --git a/examples/generics/where/input.md b/examples/generics/where/input.md new file mode 100644 index 0000000000..ba1774de3a --- /dev/null +++ b/examples/generics/where/input.md @@ -0,0 +1,27 @@ +A `where` clause is an alternate way to express a bound. It is done by +expressing the bound immediately before the opening `{` instead of at the +types first mention. Some reasons a `where` is useful include: + +* It is clearer to specify the generic types and bounds separately than +together. For example, these two are equivalent: + +```rust +impl MyTrait for YourType {} +impl MyTrait for YourType where + A: TraitB + TraitC, + D: TraitE + TraitF {} +``` + +* `where` clauses are more expressive than the normal syntax. They can +apply bounds to arbitrary expressions rather than just types. The +following example cannot be directly expressed without a `where` clause: + +{where.play} + +### See also: + +[RFC][where], [`struct`s][structs], and [`trait`s][traits] + +[structs]: /custom_types/structs.html +[traits]: /trait.html +[where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md diff --git a/examples/generics/where/where.rs b/examples/generics/where/where.rs new file mode 100644 index 0000000000..e112a8e3c6 --- /dev/null +++ b/examples/generics/where/where.rs @@ -0,0 +1,23 @@ +use std::fmt::Debug; + +trait PrintInOption { + fn print_in_option(self); +} + +impl PrintInOption for T where + // Without a `where` clause we would have to express this as + // `T: Debug` or use some other method to indirectly approach + // this. The bound we want though is `Option: Debug` because + // that's what being printed. To do otherwise would be to use + // the wrong bound. This requires a `where` clause. + Option: Debug { + fn print_in_option(self) { + println!("{:?}", Some(self)); + } +} + +fn main() { + let vec = vec![1, 2, 3]; + + vec.print_in_option(); +} diff --git a/examples/structure.json b/examples/structure.json index ed99dfb93d..0d67bec25e 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -83,7 +83,20 @@ ] } ] }, { "id": "generics", "title": "Generics", "children": [ + { "id": "gen_fn", "title": "Functions", "children": null }, { "id": "impl", "title": "Implementation", "children": null }, + { "id": "gen_trait", "title": "Traits", "children": null }, + { "id": "bounds", "title": "Bounds", "children": [ + { "id": "testcase_empty", "title": "Testcase: empty bounds", "children": null } + ] }, + { "id": "multi_bounds", "title": "Multiple bounds", "children": null }, + { "id": "where", "title": "Where clauses", "children": null }, + { "id": "assoc_types", "title": "Associated types", "children": [ + { "id": "the_problem", "title": "The problem", "children": null }, + { "id": "the_solution", "title": "The solution", "children": null }, + { "id": "constrain", "title": "Constraining", "children": null }, + { "id": "testcase_add", "title": "Testcase: Add", "children": null } + ] }, { "id": "phantom", "title": "Phantom types", "children": [ { "id": "units", "title": "Unit conversions", "children": null } ] } From 5b3cd5f3a95784555e710f6264301c6d9ccd01d4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:21:29 -0400 Subject: [PATCH 0248/1122] Update to indexed syntax --- examples/generics/impl/impl.rs | 12 ++---------- examples/generics/phantom/units/units.rs | 5 +---- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/examples/generics/impl/impl.rs b/examples/generics/impl/impl.rs index 61a4aed01f..a8fbde66f7 100644 --- a/examples/generics/impl/impl.rs +++ b/examples/generics/impl/impl.rs @@ -3,20 +3,12 @@ struct GenTup(T,); // impl of Tup impl Tup { - fn value(&self) -> &f64 { - let &Tup ( ref val ) = self; - - val - } + fn value(&self) -> &f64 { &self.0 } } // impl of GenTup for a generic type `T` impl GenTup { - fn value(&self) -> &T { - let &GenTup (ref val) = self; - - val - } + fn value(&self) -> &T { &self.0 } } fn main() { diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index 8f7ad7cbea..39d28ee12f 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -35,10 +35,7 @@ impl + Clone + Copy> Add> type Output = Length; fn add(self, r: Length) -> Length { - let Length(ref left, _) = self; - let Length(ref right, _) = r; - - Length(*left + *right, PhantomData) + Length(self.0 + r.0, PhantomData) } } From 677b53e5ef2e600f06e1e0339b4e5bea4df749c8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:21:59 -0400 Subject: [PATCH 0249/1122] Fix see also --- examples/generics/phantom/input.md | 2 +- examples/generics/phantom/units/input.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 8011bdee07..634b0f0d15 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -5,7 +5,7 @@ at compile time; they have no run-time behavior. {phantom.play} -###See also: +### See also: [Derive](http://rustbyexample.com/trait/derive.html), [struct](http://rustbyexample.com/structs.html), and diff --git a/examples/generics/phantom/units/input.md b/examples/generics/phantom/units/input.md index a8d68263e1..bc2bc0f541 100644 --- a/examples/generics/phantom/units/input.md +++ b/examples/generics/phantom/units/input.md @@ -2,7 +2,7 @@ A useful method of unit conversions: {units.play} -###See also: +### See also: [Borrowing (`&`)](http://rustbyexample.com/borrow.html), [Bounds (`X: Y`)](http://rustbyexample.com/bounds.html), From dc1bf066657b64322a5ba7a2cddcf97b613f9d95 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:23:16 -0400 Subject: [PATCH 0250/1122] Fix links --- examples/generics/phantom/input.md | 6 +++--- examples/generics/phantom/units/input.md | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 634b0f0d15..39e9d0336c 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -7,6 +7,6 @@ at compile time; they have no run-time behavior. ### See also: -[Derive](http://rustbyexample.com/trait/derive.html), -[struct](http://rustbyexample.com/structs.html), and -[TupleStructs](http://rustbyexample.com/structs.html) +[Derive](/trait/derive.html), +[struct](/custom_types/structs.html), and +[TupleStructs](/custom_types/structs.html) diff --git a/examples/generics/phantom/units/input.md b/examples/generics/phantom/units/input.md index bc2bc0f541..7783345595 100644 --- a/examples/generics/phantom/units/input.md +++ b/examples/generics/phantom/units/input.md @@ -4,12 +4,12 @@ A useful method of unit conversions: ### See also: -[Borrowing (`&`)](http://rustbyexample.com/borrow.html), -[Bounds (`X: Y`)](http://rustbyexample.com/bounds.html), -[enum](http://rustbyexample.com/enum.html), -[impl & self](http://rustbyexample.com/methods.html), -[Overloading](http://rustbyexample.com/ops.html), -[ref](http://rustbyexample.com/borrow/ref.html), -[Traits (`X for Y`)](http://rustbyexample.com/trait.html), and -[TupleStructs](http://rustbyexample.com/structs.html). +[Borrowing (`&`)](/scope/borrow.html), +[Bounds (`X: Y`)](/trait/bounds.html), +[enum](/custom_types/enum.html), +[impl & self](/fn/methods.html), +[Overloading](/trait/ops.html), +[ref](/scope/borrow/ref.html), +[Traits (`X for Y`)](/trait.html), and +[TupleStructs](/custom_types/structs.html). From 50f30edbb03039a7bef7a61b8e11e749c83d9c18 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:24:01 -0400 Subject: [PATCH 0251/1122] Revise explanation on phantom units testcase --- examples/generics/phantom/units/input.md | 25 +++++++++++++++++++++++- examples/generics/phantom/units/units.rs | 25 ++++-------------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/examples/generics/phantom/units/input.md b/examples/generics/phantom/units/input.md index 7783345595..373c219dd4 100644 --- a/examples/generics/phantom/units/input.md +++ b/examples/generics/phantom/units/input.md @@ -1,4 +1,27 @@ -A useful method of unit conversions: +A useful method of unit conversions can be examined by implementing `Add` +for a phantom type. The `Add` `trait` is examined below: + +```rust +// This construction would impose: `Self + RHS = Output`. +pub trait Add { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +// So, `Output` must be `T` and therefore, `T + T = T`. +impl Add for T {} + +// Similarly, this imposes: `S + S = S` can be +// added only when `T + T = T`. +impl> Add for S where + T: Add { + type Output = S; + ... +} +``` + +The whole implementation: {units.play} diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/units/units.rs index 39d28ee12f..38e332d037 100644 --- a/examples/generics/phantom/units/units.rs +++ b/examples/generics/phantom/units/units.rs @@ -11,27 +11,10 @@ struct Mm; #[derive(Debug, Clone, Copy)] struct Length(T,PhantomData); -/// impl X for Y {} means "implement the trait `X` for the Type `Y`" -/// The following lines implement the `Add` trait for Length. -/// -/// The `` after `impl` declares two generic -/// types, `Unit`, which can be any type, and `T`, which is a type that -/// must implement both traits `Copy` (which means no need to borrow, -/// move, or clone; you can just pass in a variable, and both the caller -/// and callee will own their own copy), and the trait `Add`. -/// -/// `Add` means that the type implements Add, taking in a T -/// (meaning an i32 plus an i32, or an f64 plus an f64, etc.), and giving -/// back a T (i32 + i32 = i32). -/// -/// So, this impl implements `Add` for `Length`, -/// which means you can add a `Length` to another `Length` of the same type. -/// -/// `type Output = Length` means that this impl gives back a -/// `Length`, so that -/// `Length + Length = Length` -impl + Clone + Copy> Add> - for Length { +// This is similar to the header except `T` must also +// implement `Clone` and `Copy. +impl Add> for Length where + T: Add + Clone + Copy { type Output = Length; fn add(self, r: Length) -> Length { From 188085cbac67cc9497aa30e8f652988cff19d9fc Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 14 May 2015 01:24:34 -0400 Subject: [PATCH 0252/1122] Rename phantom types testcase --- examples/generics/phantom/{units => testcase_units}/input.md | 0 examples/generics/phantom/{units => testcase_units}/units.rs | 0 examples/structure.json | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename examples/generics/phantom/{units => testcase_units}/input.md (100%) rename examples/generics/phantom/{units => testcase_units}/units.rs (100%) diff --git a/examples/generics/phantom/units/input.md b/examples/generics/phantom/testcase_units/input.md similarity index 100% rename from examples/generics/phantom/units/input.md rename to examples/generics/phantom/testcase_units/input.md diff --git a/examples/generics/phantom/units/units.rs b/examples/generics/phantom/testcase_units/units.rs similarity index 100% rename from examples/generics/phantom/units/units.rs rename to examples/generics/phantom/testcase_units/units.rs diff --git a/examples/structure.json b/examples/structure.json index 0d67bec25e..e3532f0267 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -98,7 +98,7 @@ { "id": "testcase_add", "title": "Testcase: Add", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ - { "id": "units", "title": "Unit conversions", "children": null } + { "id": "testcase_units", "title": "Testcase: unit conversions", "children": null } ] } ] }, { "id": "scope", "title": "Scoping rules", "children": [ From 17eb5d829440bd3a33560685213823c51148f61f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 15 May 2015 12:20:36 -0700 Subject: [PATCH 0253/1122] Fix inner doc comment syntax --- examples/hello/comment/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/comment/input.md b/examples/hello/comment/input.md index 4afd7cf471..609d0290d5 100644 --- a/examples/hello/comment/input.md +++ b/examples/hello/comment/input.md @@ -7,7 +7,7 @@ a few different varieties: * *Doc comments* which are parsed into HTML library [documentation][docs]: - `/// Generate library docs for the following item.` - - `!// Generate library docs for the enclosing item.` + - `//! Generate library docs for the enclosing item.` {comment.play} From fee8ba17e62d7386d42b6a349d565ce7b9882aeb Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 16 May 2015 01:17:21 -0400 Subject: [PATCH 0254/1122] Add associated items. Rework other sections to fit it in. --- .../constrain/constrain.rs | 0 .../constrain/input.md | 0 .../generics/assoc_items/consts/consts.rs | 40 +++++++++++++++++++ examples/generics/assoc_items/consts/input.md | 7 ++++ examples/generics/assoc_items/input.md | 19 +++++++++ .../testcase_add/input.md | 0 .../testcase_add/testcase.rs | 0 .../the_problem/input.md | 0 .../the_problem/problem.rs | 0 .../types}/input.md | 8 ++-- .../types/types.rs} | 0 examples/generics/assoc_types/input.md | 17 -------- examples/structure.json | 5 ++- 13 files changed, 73 insertions(+), 23 deletions(-) rename examples/generics/{assoc_types => assoc_items}/constrain/constrain.rs (100%) rename examples/generics/{assoc_types => assoc_items}/constrain/input.md (100%) create mode 100644 examples/generics/assoc_items/consts/consts.rs create mode 100644 examples/generics/assoc_items/consts/input.md create mode 100644 examples/generics/assoc_items/input.md rename examples/generics/{assoc_types => assoc_items}/testcase_add/input.md (100%) rename examples/generics/{assoc_types => assoc_items}/testcase_add/testcase.rs (100%) rename examples/generics/{assoc_types => assoc_items}/the_problem/input.md (100%) rename examples/generics/{assoc_types => assoc_items}/the_problem/problem.rs (100%) rename examples/generics/{assoc_types/the_solution => assoc_items/types}/input.md (76%) rename examples/generics/{assoc_types/the_solution/solution.rs => assoc_items/types/types.rs} (100%) delete mode 100644 examples/generics/assoc_types/input.md diff --git a/examples/generics/assoc_types/constrain/constrain.rs b/examples/generics/assoc_items/constrain/constrain.rs similarity index 100% rename from examples/generics/assoc_types/constrain/constrain.rs rename to examples/generics/assoc_items/constrain/constrain.rs diff --git a/examples/generics/assoc_types/constrain/input.md b/examples/generics/assoc_items/constrain/input.md similarity index 100% rename from examples/generics/assoc_types/constrain/input.md rename to examples/generics/assoc_items/constrain/input.md diff --git a/examples/generics/assoc_items/consts/consts.rs b/examples/generics/assoc_items/consts/consts.rs new file mode 100644 index 0000000000..49743612e9 --- /dev/null +++ b/examples/generics/assoc_items/consts/consts.rs @@ -0,0 +1,40 @@ +#![feature(associated_consts)] + +// 2 null structs. +#[allow(dead_code)] +struct Num; +#[allow(dead_code)] +struct Weird; + +// Trait to define zero. +trait Zero { + // `const` requires a type. Use a default of `0`. + const ZERO: i32 = 0; +} + +// Trait to define one. +trait One { + // Can use the type `Self` which defers to the `impl`. + const ONE: Self; +} + +// Use the default. +impl Zero for Num {} + +// Change the default. +impl Zero for Weird { + const ZERO: i32 = 9; +} + +// Define one for `i32`. +impl One for i32 { + // Type must agree with the `Self` type: `i32`. + const ONE: i32 = 1; +} + +fn main() { + // These calls use the `UFCS` calling syntax. + println!("ZERO for Num is {}", Num::ZERO); // Default. + println!("ZERO for Weird is {}", Weird::ZERO); // Customized. + println!("ONE for i32 is {}", i32::ONE); // Type specified in `impl`. +} diff --git a/examples/generics/assoc_items/consts/input.md b/examples/generics/assoc_items/consts/input.md new file mode 100644 index 0000000000..a3bf4b92c3 --- /dev/null +++ b/examples/generics/assoc_items/consts/input.md @@ -0,0 +1,7 @@ +`trait`s holding `const`s are called Associated `const`s: + +{consts.play} + +### See also: + +[UFCS RFC](https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md) diff --git a/examples/generics/assoc_items/input.md b/examples/generics/assoc_items/input.md new file mode 100644 index 0000000000..0eb7502e05 --- /dev/null +++ b/examples/generics/assoc_items/input.md @@ -0,0 +1,19 @@ +Associated Items is an extension to `trait` generics which encompasses a set +of rules pertaining to [`item`s][items] of various types. It allows `trait`s +to internally define a few new items including: + +* `const`s via the keyword `const`. +* `type`s via the keyword `type`. This is called an *output* type. + +Some advantages are: + +* `trait`s now have access to `const`s. +* `type`s get simpler usage patterns when the `trait` is generic over +containers. + +### See also: + +[RFC]( +https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md +) +[items]: http://doc.rust-lang.org/reference.html#items diff --git a/examples/generics/assoc_types/testcase_add/input.md b/examples/generics/assoc_items/testcase_add/input.md similarity index 100% rename from examples/generics/assoc_types/testcase_add/input.md rename to examples/generics/assoc_items/testcase_add/input.md diff --git a/examples/generics/assoc_types/testcase_add/testcase.rs b/examples/generics/assoc_items/testcase_add/testcase.rs similarity index 100% rename from examples/generics/assoc_types/testcase_add/testcase.rs rename to examples/generics/assoc_items/testcase_add/testcase.rs diff --git a/examples/generics/assoc_types/the_problem/input.md b/examples/generics/assoc_items/the_problem/input.md similarity index 100% rename from examples/generics/assoc_types/the_problem/input.md rename to examples/generics/assoc_items/the_problem/input.md diff --git a/examples/generics/assoc_types/the_problem/problem.rs b/examples/generics/assoc_items/the_problem/problem.rs similarity index 100% rename from examples/generics/assoc_types/the_problem/problem.rs rename to examples/generics/assoc_items/the_problem/problem.rs diff --git a/examples/generics/assoc_types/the_solution/input.md b/examples/generics/assoc_items/types/input.md similarity index 76% rename from examples/generics/assoc_types/the_solution/input.md rename to examples/generics/assoc_items/types/input.md index 6a073c6aff..8d20e2baef 100644 --- a/examples/generics/assoc_types/the_solution/input.md +++ b/examples/generics/assoc_items/types/input.md @@ -1,6 +1,6 @@ -Associated types moves the internal types locally into the trait to be -called *output* types. This shields future users of the trait from the -substantial boilerplate previously required. For example: +Associated types forms the solution by moving the internal types locally into +the trait to be called *output* types. This shields future users of the trait +from the substantial boilerplate previously required. For example: ```rust // The original trait @@ -32,4 +32,4 @@ fn difference(container: &C) -> i32 where fn difference(container: &C) -> i32 { ... } ``` -{solution.play} +{types.play} diff --git a/examples/generics/assoc_types/the_solution/solution.rs b/examples/generics/assoc_items/types/types.rs similarity index 100% rename from examples/generics/assoc_types/the_solution/solution.rs rename to examples/generics/assoc_items/types/types.rs diff --git a/examples/generics/assoc_types/input.md b/examples/generics/assoc_types/input.md deleted file mode 100644 index 4e6e05cb17..0000000000 --- a/examples/generics/assoc_types/input.md +++ /dev/null @@ -1,17 +0,0 @@ -Associated Items is an extension to `trait` generics which adds a different -feel and style to generics. It encompasses a set of rules pertaining to -[`item`s][items] of various types. The main one under under consideration here -is Associated Types. Associated Types adds one new concept: - -* `trait`s can now internally define a `type` via the keyword `type`. This is -called an *output* type. - -The result is much simpler usage patterns when the `trait` is generic over -containers. - -### See also: - -[RFC]( -https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md -) -[items]: http://doc.rust-lang.org/reference.html#items diff --git a/examples/structure.json b/examples/structure.json index e3532f0267..4cbef9d583 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -91,10 +91,11 @@ ] }, { "id": "multi_bounds", "title": "Multiple bounds", "children": null }, { "id": "where", "title": "Where clauses", "children": null }, - { "id": "assoc_types", "title": "Associated types", "children": [ + { "id": "assoc_items", "title": "Associated items", "children": [ { "id": "the_problem", "title": "The problem", "children": null }, - { "id": "the_solution", "title": "The solution", "children": null }, + { "id": "types", "title": "Associated types", "children": null }, { "id": "constrain", "title": "Constraining", "children": null }, + { "id": "consts", "title": "Associated consts", "children": null }, { "id": "testcase_add", "title": "Testcase: Add", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ From 5442ecc586b1f1b0b4f9bbe87d9a7b16a8ec8c4a Mon Sep 17 00:00:00 2001 From: Han Seoul-Oh Date: Sat, 16 May 2015 11:44:00 -0700 Subject: [PATCH 0255/1122] Fix typo about most common formatting trait --- examples/hello/print/fmt/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/fmt/input.md b/examples/hello/print/fmt/input.md index d2c03fd481..95c38aa70a 100644 --- a/examples/hello/print/fmt/input.md +++ b/examples/hello/print/fmt/input.md @@ -9,7 +9,7 @@ The same variable (`foo`) can be formatted differently depending on which *argument type* is used: `X` vs `o` vs *unspecified*. This formatting functionality is implemented via traits, and there is one trait -for each argument type. The most common formatting trait is `Debug`, which +for each argument type. The most common formatting trait is `Display`, which handles cases where the argument type is left unspecified: `{}` for instance. {show.play} From c0f01fd7f1cff3ed728cdf43e54d48d0e8542bf2 Mon Sep 17 00:00:00 2001 From: vthriller Date: Sun, 17 May 2015 16:26:44 +0300 Subject: [PATCH 0256/1122] minor fixes: typo and emphasizing --- examples/primitives/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/primitives/input.md b/examples/primitives/input.md index becf7e4c02..dfd07daf6f 100644 --- a/examples/primitives/input.md +++ b/examples/primitives/input.md @@ -9,8 +9,8 @@ Rust provides access to a wide variety of `primitives`. A sample includes: * arrays like `[1, 2, 3]` * tuples like `(1, true)` -Variables can be always be *type annotated*. Numbers may additionally be -annotated via a *suffix* or by *default*. Integers default to `i32` and +Variables can always be *type annotated*. Numbers may additionally be +annotated via a *suffix* or *by default*. Integers default to `i32` and floats to `f64`. {primitives.play} From b67c8d6920e7510f21eb1d166c92badd1b538b21 Mon Sep 17 00:00:00 2001 From: vthriller Date: Sun, 17 May 2015 16:36:21 +0300 Subject: [PATCH 0257/1122] hey, no self-linking! this isn't about recursion for kids --- examples/primitives/literals/input.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index 8066b7267c..3b74f08948 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -10,9 +10,7 @@ Underscores can be inserted in numeric literals to improve readability, e.g. We need to tell the compiler the type of the literals we use. For now, we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. -We'll cover the type system in [another chapter][primitives], and give more -details about type annotating literals in -[their own section][primitive_literals]. +We'll cover the type system in [another chapter][primitives]. The operators available and their precedence are similar to other [C-like languages][op-prec]. @@ -21,4 +19,3 @@ The operators available and their precedence are similar to other [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages [primitives]: /primitives.html -[primitive_literals]: /primitives/literals.html From 00e953a12520b1ff7e5ee940f0b4f38a90dbbe89 Mon Sep 17 00:00:00 2001 From: vthriller Date: Sun, 17 May 2015 16:40:52 +0300 Subject: [PATCH 0258/1122] parent link is also redundant (since c5e6e57) --- examples/primitives/literals/input.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index 3b74f08948..2c027333c4 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -10,7 +10,6 @@ Underscores can be inserted in numeric literals to improve readability, e.g. We need to tell the compiler the type of the literals we use. For now, we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. -We'll cover the type system in [another chapter][primitives]. The operators available and their precedence are similar to other [C-like languages][op-prec]. @@ -18,4 +17,3 @@ The operators available and their precedence are similar to other {literals.play} [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages -[primitives]: /primitives.html From 0d3a1e1cc0cdbe82769332d9348b9b5a65e34110 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 23 May 2015 14:25:02 -0400 Subject: [PATCH 0259/1122] Use two instead of 2 --- examples/generics/assoc_items/types/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/assoc_items/types/types.rs b/examples/generics/assoc_items/types/types.rs index c685a92aa9..85bc7a25e5 100644 --- a/examples/generics/assoc_items/types/types.rs +++ b/examples/generics/assoc_items/types/types.rs @@ -1,6 +1,6 @@ struct Container(i32, i32); -// A trait which will check to see if 2 items are stored inside of container. +// A trait which will check to see if two items are stored inside of container. // Also retrieves first or last value. trait Contains { // Define generic types here which methods will be able utilize. From 1580f7f920a3fabef8513786395fff0c78e70f09 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 17 May 2015 20:38:14 -0300 Subject: [PATCH 0260/1122] Rust by Example uses the latest nightly build --- examples/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/README.md b/examples/README.md index b6ca08f54c..de3c3ffc97 100644 --- a/examples/README.md +++ b/examples/README.md @@ -11,9 +11,8 @@ for this site][home]. Be sure to have Rust [installed][install] and the [docs][std] at hand, and let's start! -*Note*: Rust by Example follows the nightly builds until the beta or possibly -the 1.0.0 final release. If you're following along on your computer, make sure -to have the latest Rust installed. +*Note*: Rust by Example uses the latest nightly build. If you're +following along on your computer, make sure to have it installed. [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html From caa77d7d0d21fa2f66be51eae98f60f7bf4d0ab0 Mon Sep 17 00:00:00 2001 From: vectorijk Date: Sun, 24 May 2015 21:24:01 -0700 Subject: [PATCH 0261/1122] std/hash: fix wiki link unreachable --- examples/std/hash/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/std/hash/input.md b/examples/std/hash/input.md index 55dccb0aa2..bffd1f6edc 100644 --- a/examples/std/hash/input.md +++ b/examples/std/hash/input.md @@ -13,6 +13,6 @@ with a default initial capacity (recommended). For more information on how hashing and hash maps (sometimes called hash tables) work, have a look at -[Wikipedia][wiki-hash] +[Hash Table Wikipedia][wiki-hash] -[wiki-hash]: (http://en.wikipedia.org/wiki/Hash_table) +[wiki-hash]: http://en.wikipedia.org/wiki/Hash_table From 57d61a45a1bed98bbb279575a05cb7ef0e26fabc Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 18 May 2015 01:08:44 -0300 Subject: [PATCH 0262/1122] Fix traits layout --- examples/hello/print/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index 0d98399e2c..cc807db4ab 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -10,7 +10,7 @@ be checked at compile time. {print.play} -[`std::fmt`][fmt] contains many [`trait`s][traits] which govern the display +[`std::fmt`][fmt] contains many [`traits`][traits] which govern the display of text. The base form of two important ones are listed below: * `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes. @@ -23,7 +23,7 @@ for these types. To print text for custom types, more steps are required. ### See also: [`std::fmt`][fmt], [macros][macros], [`struct`][structs], -and [`trait`s][traits] +and [`traits`][traits] [fmt]: http://doc.rust-lang.org/std/fmt/ [macros]: /macros.html From 947ca5d4682a5580be7e3a71e8a9d5410ed53642 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 18 May 2015 01:09:33 -0300 Subject: [PATCH 0263/1122] Format macro the same way as the rest of the concepts --- examples/hello/print/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index cc807db4ab..cb26fdddec 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -1,4 +1,4 @@ -Printing is handled by a series of [macros][macros] defined in [`std::fmt`][fmt] +Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt] some of which include: * `format!`: write formatted text to [`String`][string] @@ -22,7 +22,7 @@ for these types. To print text for custom types, more steps are required. ### See also: -[`std::fmt`][fmt], [macros][macros], [`struct`][structs], +[`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], and [`traits`][traits] [fmt]: http://doc.rust-lang.org/std/fmt/ From 79a7637fe42b3f10ae798c76f98b49b9c007a152 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 18 May 2015 01:23:09 -0300 Subject: [PATCH 0264/1122] Fix traits formatting --- examples/hello/print/print_debug/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_debug/input.md b/examples/hello/print/print_debug/input.md index b4dc3ff0ee..b48db8686e 100644 --- a/examples/hello/print/print_debug/input.md +++ b/examples/hello/print/print_debug/input.md @@ -1,4 +1,4 @@ -All types which want to use `std::fmt` formatting `trait`s require an +All types which want to use `std::fmt` formatting `traits` require an implementation to be printable. Automatic implementations are only provided for types such as in the `std` library. All others *must* be manually implemented somehow. From 791d0f60d24e0f581627905d67aaea07d6eaf6d3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 18 May 2015 01:59:24 -0300 Subject: [PATCH 0265/1122] Fix traits formatting in print_display --- examples/hello/print/print_display/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 1d6325a8b6..6b87002984 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -44,7 +44,7 @@ This is not a problem though because for any new *container* type which is {display.play} So, `fmt::Display` has been implemented but `fmt::Binary` has not, and -therefore cannot be used. `std::fmt` has many such [`trait`s][traits] and +therefore cannot be used. `std::fmt` has many such [`traits`][traits] and each requires it's own implementation. This is detailed further in [`std::fmt`][fmt]. From d34e545d9a708e9b9f742017738ea38e1e3ec704 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 19 May 2015 09:38:25 -0300 Subject: [PATCH 0266/1122] Make import via use a bit more clear --- examples/hello/print/print_display/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 6b87002984..1327fe83bc 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -4,7 +4,7 @@ customize the output appearance. This is done by manually implementing looks like this: ```rust -// Import the `fmt` module to make it available via `use`. +// Import (via `use`) the `fmt` module to make it available. use std::fmt; // Define a structure which `fmt::Display` will be implemented for. This is simply From b4b3d40887c95030a521bf27f45e74cd3439076f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 19 May 2015 10:32:41 -0300 Subject: [PATCH 0267/1122] Rephrase comments are not read by the compiler --- examples/hello/comment/comment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/comment/comment.rs b/examples/hello/comment/comment.rs index beebd8a393..78921d78bf 100644 --- a/examples/hello/comment/comment.rs +++ b/examples/hello/comment/comment.rs @@ -1,7 +1,7 @@ fn main() { // This is an example of a line comment // Notice how there are two slashes at the beginning of the line - // And that anything written inside these will not be read by the compiler + // And that nothing written inside these will be read by the compiler // println!("Hello, world!"); From edd7059eb1f56e690fd4140f4a5923e049ea7dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Pan=C4=83?= Date: Wed, 27 May 2015 13:57:54 +0300 Subject: [PATCH 0268/1122] hello/print/print_display: changed "structure" to "tuple struct" --- examples/hello/print/print_display/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 1d6325a8b6..805878fa72 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -8,7 +8,7 @@ looks like this: use std::fmt; // Define a structure which `fmt::Display` will be implemented for. This is simply -// a structure containing an `i32` bound to the name `Structure`. +// a tuple struct containing an `i32` bound to the name `Structure`. struct Structure(i32); // In order to use the `{}` marker, the trait `fmt::Display` must be implemented From 12916ca9a5eccb9cf5a00ac6c4c07af2b0d91a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Pan=C4=83?= Date: Wed, 27 May 2015 14:11:48 +0300 Subject: [PATCH 0269/1122] trait/derive: changed the format pattern to "{:?}" for the Debug trait example --- examples/trait/derive/derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/derive/derive.rs b/examples/trait/derive/derive.rs index 3c067389eb..8ef73fa27a 100644 --- a/examples/trait/derive/derive.rs +++ b/examples/trait/derive/derive.rs @@ -22,7 +22,7 @@ fn main() { // Error! `Seconds` can't be printed, because it doesn't implement the // `Debug` trait - //println!("One second looks like: {}", _one_second); + //println!("One second looks like: {:?}", _one_second); // TODO ^ Try uncommenting this line // Error: `Seconds` can't be compared, because it doesn't implement the From 6e906565a86be273104cc72c53a65bb529332138 Mon Sep 17 00:00:00 2001 From: Letheed Date: Sun, 31 May 2015 14:34:36 +0200 Subject: [PATCH 0270/1122] generics/phantom/testcase_units: alleviate the syntactical heaviness of the types and bounds --- .../generics/phantom/testcase_units/input.md | 16 +++++++------ .../generics/phantom/testcase_units/units.rs | 24 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 373c219dd4..108663b77a 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -3,20 +3,22 @@ for a phantom type. The `Add` `trait` is examined below: ```rust // This construction would impose: `Self + RHS = Output`. +// where RHS and Self are of the same type. pub trait Add { type Output; fn add(self, rhs: RHS) -> Self::Output; } -// So, `Output` must be `T` and therefore, `T + T = T`. -impl Add for T {} +// `Output` must be `T` so that `T + T = T`. +impl Add for T { + type Output = T; + ... +} -// Similarly, this imposes: `S + S = S` can be -// added only when `T + T = T`. -impl> Add for S where - T: Add { - type Output = S; +// Similarly, this imposes: `T + T = T` +impl Add for T { + type Output = T; ... } ``` diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index 38e332d037..3fd024c1b7 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -8,26 +8,30 @@ struct Inch; struct Mm; /// Length is phantom type with hidden parameter `Unit` +/// f64 already implements the Clone and Copy traits #[derive(Debug, Clone, Copy)] -struct Length(T,PhantomData); +struct Length(f64,PhantomData); -// This is similar to the header except `T` must also -// implement `Clone` and `Copy. -impl Add> for Length where - T: Add + Clone + Copy { - type Output = Length; +/// The Add trait defines the behavior of the `+` operator +impl Add for Length { + type Output = Length; - fn add(self, r: Length) -> Length { - Length(self.0 + r.0, PhantomData) + // add() returns a new Length struct containing the sum + fn add(self, rhs: Length) -> Length { + // `+` calls the Add implementation for f64 + Length(self.0 + rhs.0, PhantomData) } } fn main() { // Specialize one_foot to have hidden parameter `Inch` - let one_foot: Length = Length(12.0, PhantomData); + let one_foot: Length = Length(12.0, PhantomData); // one_meter has hidden parameter `Mm` - let one_meter: Length = Length(1000.0, PhantomData); + let one_meter: Length = Length(1000.0, PhantomData); + // `+` calls the add() method we implemented for Length + // Since Length implements Clone + Copy, add() does not consume + // one_foot and one_meter but makes a copy of them in `self` and `rhs` let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; From 293bc7e13aaa980c420fc2dc43fe77a26ca37642 Mon Sep 17 00:00:00 2001 From: Akshay S Dinesh Date: Sun, 31 May 2015 18:39:34 +0530 Subject: [PATCH 0271/1122] meta/doc fix old link --- examples/meta/doc/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/meta/doc/input.md b/examples/meta/doc/input.md index 31dc60057c..e386b3d5ac 100644 --- a/examples/meta/doc/input.md +++ b/examples/meta/doc/input.md @@ -4,5 +4,5 @@ documentation. They are denoted by a `///`, and support [Markdown][2]. {doc.play} -[1]: https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc.md +[1]: http://doc.rust-lang.org/book/documentation.html [2]: https://en.wikipedia.org/wiki/Markdown From e2ac5aa45c4021e9464fc2d47a4c58129a9bb560 Mon Sep 17 00:00:00 2001 From: Letheed Date: Mon, 1 Jun 2015 04:02:50 +0200 Subject: [PATCH 0272/1122] generics/phantom/testcase_units: drop one of the header blocks for clarity --- examples/generics/phantom/testcase_units/input.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 108663b77a..944fecf30a 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -10,13 +10,7 @@ pub trait Add { fn add(self, rhs: RHS) -> Self::Output; } -// `Output` must be `T` so that `T + T = T`. -impl Add for T { - type Output = T; - ... -} - -// Similarly, this imposes: `T + T = T` +// `Output` must be `T` so that `T + T = T` impl Add for T { type Output = T; ... From a8c37f0283bc194b184f58dcd2aa5534acc4a65c Mon Sep 17 00:00:00 2001 From: Letheed Date: Mon, 1 Jun 2015 13:09:11 +0200 Subject: [PATCH 0273/1122] generics/phantom/testcase_units: correct comment on RHS defaulting to Self --- examples/generics/phantom/testcase_units/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 944fecf30a..9682a4928b 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -3,7 +3,7 @@ for a phantom type. The `Add` `trait` is examined below: ```rust // This construction would impose: `Self + RHS = Output`. -// where RHS and Self are of the same type. +// where RHS defaults to Self if not specified in the implementation pub trait Add { type Output; From 3ca5b861fd3072449ca114a0204bd4ccda246e76 Mon Sep 17 00:00:00 2001 From: Letheed Date: Wed, 3 Jun 2015 02:38:57 +0200 Subject: [PATCH 0274/1122] std/hash: HashMap::insert() returns Option, not bool --- examples/std/hash/hash.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/std/hash/hash.rs b/examples/std/hash/hash.rs index 4cebfa8ffa..cf4dfe29d1 100644 --- a/examples/std/hash/hash.rs +++ b/examples/std/hash/hash.rs @@ -24,8 +24,8 @@ fn main() { _ => println!("Don't have Daniel's number."), } - // `HashMap::insert()` returns true - // if the inserted value is new, false otherwise + // `HashMap::insert()` returns `None` + // if the inserted value is new, `Some(value)` otherwise contacts.insert("Daniel", "164-6743"); match contacts.get(&"Ashley") { From 4317c7192138871e5ffc304aef763c4dd0a8d927 Mon Sep 17 00:00:00 2001 From: Christian Stadelmann Date: Thu, 4 Jun 2015 21:18:46 +0200 Subject: [PATCH 0275/1122] Typos fixed --- examples/unsafe/input.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index eb4c828b24..9e9dc0a3e2 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -1,6 +1,6 @@ As an introduction to this section, to borrow from [the official docs]( http://doc.rust-lang.org/master/guide-unsafe.html), "one should try to -minimize the amount of unsafe code in a code base." With that in mind, let's +minimize the amount of unsafe code in a code base." With that in mind, let's get started! Unsafe blocks in Rust are used to bypass protections put in place by the compiler; specifically, there are four primary things that unsafe blocks are @@ -15,24 +15,24 @@ used for: ### Raw Pointers Raw pointers `*` and references `&T` function similarly, but references are always safe because they are guaranteed to point to valid data due to the -borrow checker. Dereferencing a raw pointer can only be done through an unsafe +borrow checker. Dereferencing a raw pointer can only be done through an unsafe block. {pointer.rs} ### Transmute Allows simple conversion from one type to another, however both types must have -the same size and alignment +the same size and alignment: {transmute.rs} ### Inline Assembly -Inline assembly functions very similarly to the inline assembly of c, which +Inline assembly functions very similarly to the inline assembly of C, which makes sense considering its implementation is not handled by rust, rather by the LLVM. It allows for direct access to assembly manipulation, which can massively increase speed, but it can also decrease portability and stability. In most cases the compiler will optimize your rust code to better assembly than -you could write, so in most instances it is not worth it. The first parameter +you could write, so in most instances it is not worth it. The first parameter of asm!() is the format of the assembly, the parameter following the colon is the output variable, and the parameter(s) following that are the input variables. From ee627386a9f34746aaf319b677808678f191ff08 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Fri, 5 Jun 2015 17:46:21 -0700 Subject: [PATCH 0276/1122] std_misc/process/pipe: Update comments to match current API. --- examples/std_misc/process/pipe/pipe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/std_misc/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs index 29fdb71ce0..be7cf1e3d6 100644 --- a/examples/std_misc/process/pipe/pipe.rs +++ b/examples/std_misc/process/pipe/pipe.rs @@ -16,7 +16,9 @@ fn main() { }; { - // Write a string to the stdin of `wc` + // Write a string to the stdin of `wc`. + // stdin has type `Option`, but since we know this instance + // must have one, we can directly `unwrap` it. match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { Err(why) => panic!("couldn't write to wc stdin: {}", Error::description(&why)), @@ -28,9 +30,7 @@ fn main() { // input we just sent } - // The `stdout` field also has type `Option` - // the `as_mut` method will return a mutable reference to the value - // wrapped in a `Some` variant + // The `stdout` field also has type `Option` so must be unwrapped. let mut s = String::new(); match process.stdout.unwrap().read_to_string(&mut s) { Err(why) => panic!("couldn't read wc stdout: {}", From 0e8e227d9e171bb0287359b40cf457e77bdb004c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 7 Jun 2015 23:31:28 -0300 Subject: [PATCH 0277/1122] Remove unused and wrong main function --- examples/macros/dry/dry.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index 81205fc79c..2ff0578d9b 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -32,14 +32,6 @@ op!(add_assign, Add, +=, add); op!(mul_assign, Mul, *=, mul); op!(sub_assign, Sub, -=, sub); -fn main() { - let mut xs = iter::repeat(0f64).take(5).collect(); - let ys = iter::repeat(1f64).take(6).collect(); - - // this operation will fail at runtime - add_assign(&mut xs, &ys); -} - mod test { use std::iter; macro_rules! test { From f90d942f170796f57885fc86f7f2c1c25a11100b Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 7 Jun 2015 21:29:21 -0700 Subject: [PATCH 0278/1122] Additional markup tweaks. --- examples/std_misc/process/pipe/pipe.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/std_misc/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs index be7cf1e3d6..41747b255b 100644 --- a/examples/std_misc/process/pipe/pipe.rs +++ b/examples/std_misc/process/pipe/pipe.rs @@ -16,8 +16,9 @@ fn main() { }; { - // Write a string to the stdin of `wc`. - // stdin has type `Option`, but since we know this instance + // Write a string to the `stdin` of `wc`. + // + // `stdin` has type `Option`, but since we know this instance // must have one, we can directly `unwrap` it. match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { Err(why) => panic!("couldn't write to wc stdin: {}", @@ -25,9 +26,10 @@ fn main() { Ok(_) => println!("sent pangram to wc"), } - // `stdin` gets `drop`ed here, and the pipe is closed + // `stdin` gets `drop`ed here, and the pipe is closed. + // // This is very important, otherwise `wc` wouldn't start processing the - // input we just sent + // input we just sent. } // The `stdout` field also has type `Option` so must be unwrapped. From 875e3aff9c9bbdda767eaafa1fe565c9fcf42d2f Mon Sep 17 00:00:00 2001 From: Letheed Date: Mon, 8 Jun 2015 19:05:43 +0200 Subject: [PATCH 0279/1122] generics/phantom/testcase_units: polish formating --- .../generics/phantom/testcase_units/input.md | 6 ++--- .../generics/phantom/testcase_units/units.rs | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 9682a4928b..86a2d32246 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -2,15 +2,15 @@ A useful method of unit conversions can be examined by implementing `Add` for a phantom type. The `Add` `trait` is examined below: ```rust -// This construction would impose: `Self + RHS = Output`. -// where RHS defaults to Self if not specified in the implementation +// This construction would impose: `Self + RHS = Output` +// where RHS defaults to Self if not specified in the implementation. pub trait Add { type Output; fn add(self, rhs: RHS) -> Self::Output; } -// `Output` must be `T` so that `T + T = T` +// `Output` must be `T` so that `T + T = T`. impl Add for T { type Output = T; ... diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index 3fd024c1b7..39711df62b 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -7,31 +7,33 @@ struct Inch; #[derive(Debug, Clone, Copy)] struct Mm; -/// Length is phantom type with hidden parameter `Unit` -/// f64 already implements the Clone and Copy traits +/// `Length` is phantom type with hidden parameter `Unit` +/// +/// `f64` already implements the `Clone` and `Copy` traits #[derive(Debug, Clone, Copy)] struct Length(f64,PhantomData); -/// The Add trait defines the behavior of the `+` operator +/// The `Add` trait defines the behavior of the `+` operator. impl Add for Length { type Output = Length; - // add() returns a new Length struct containing the sum + // add() returns a new `Length` struct containing the sum. fn add(self, rhs: Length) -> Length { - // `+` calls the Add implementation for f64 + // `+` calls the `Add` implementation for `f64` Length(self.0 + rhs.0, PhantomData) } } fn main() { - // Specialize one_foot to have hidden parameter `Inch` + // Specialize `one_foot` to have hidden parameter `Inch` let one_foot: Length = Length(12.0, PhantomData); - // one_meter has hidden parameter `Mm` + // `one_meter` has hidden parameter `Mm` let one_meter: Length = Length(1000.0, PhantomData); - // `+` calls the add() method we implemented for Length - // Since Length implements Clone + Copy, add() does not consume - // one_foot and one_meter but makes a copy of them in `self` and `rhs` + // `+` calls the `add()` method we implemented for `Length` + // + // Since `Length` implements `Clone` + `Copy`, `add()` does not consume + // `one_foot` and `one_meter` but makes a copy of them in `self` and `rhs` let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; From 288029b27ae4fdf049746fb27666ab8b2763fe78 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 7 Jun 2015 22:46:07 -0300 Subject: [PATCH 0280/1122] Explain better the macro repeat expressions --- examples/macros/repeat/input.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/macros/repeat/input.md b/examples/macros/repeat/input.md index 2c8886f65b..5c5483e6a1 100644 --- a/examples/macros/repeat/input.md +++ b/examples/macros/repeat/input.md @@ -2,4 +2,8 @@ Macros can use `+` in the argument list to indicate that an argument may repeat at least once, or `*`, to indicate that the argument may repeat zero or more times. +In the following example, surrounding the matcher with `$(...),+` will +match one or more expression, separated by commas. +Also note that the semicolon is optional on the last case. + {repeat.play} From 2e16facf562319066da5a3dbc68770f8fc9ffdf0 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 8 Jun 2015 13:46:31 -0400 Subject: [PATCH 0281/1122] Fix warning --- examples/macros/dry/dry.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index 2ff0578d9b..fad24061fb 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -1,4 +1,3 @@ -use std::iter; use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { From 6986e2872ccdf9adc9764d53b71df6689ed73995 Mon Sep 17 00:00:00 2001 From: Letheed Date: Mon, 8 Jun 2015 23:18:53 +0200 Subject: [PATCH 0282/1122] generics/phantom/testcase_units: mostly punctiation --- .../generics/phantom/testcase_units/units.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index 39711df62b..1002e02640 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -1,15 +1,15 @@ use std::ops::Add; use std::marker::PhantomData; -/// Null enumerations to define unit types +/// Null enumerations define unit types. #[derive(Debug, Clone, Copy)] struct Inch; #[derive(Debug, Clone, Copy)] struct Mm; -/// `Length` is phantom type with hidden parameter `Unit` +/// `Length` is phantom type with hidden parameter `Unit`. /// -/// `f64` already implements the `Clone` and `Copy` traits +/// `f64` already implements the `Clone` and `Copy` traits. #[derive(Debug, Clone, Copy)] struct Length(f64,PhantomData); @@ -19,30 +19,30 @@ impl Add for Length { // add() returns a new `Length` struct containing the sum. fn add(self, rhs: Length) -> Length { - // `+` calls the `Add` implementation for `f64` + // `+` calls the `Add` implementation for `f64`. Length(self.0 + rhs.0, PhantomData) } } fn main() { - // Specialize `one_foot` to have hidden parameter `Inch` + // Specializes `one_foot` to have hidden parameter `Inch`. let one_foot: Length = Length(12.0, PhantomData); - // `one_meter` has hidden parameter `Mm` + // `one_meter` has hidden parameter `Mm`. let one_meter: Length = Length(1000.0, PhantomData); - // `+` calls the `add()` method we implemented for `Length` + // `+` calls the `add()` method we implemented for `Length`. // // Since `Length` implements `Clone` + `Copy`, `add()` does not consume - // `one_foot` and `one_meter` but makes a copy of them in `self` and `rhs` + // `one_foot` and `one_meter` but makes a copy of them in `self` and `rhs`. let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; - // Addition works + // Addition works. println!("one foot + one_foot = {:?}", two_feet); println!("one meter + one_meter = {:?}", two_meters); - // Nonsensical operations fail as they should - // Error: type mismatch + // Nonsensical operations fail as they should: + // Error: type mismatch. //let one_feter = one_foot + one_meter; } From 9953493672f69685d0060866771d0617c9c18604 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 11 Jun 2015 00:49:55 -0400 Subject: [PATCH 0283/1122] Rewrite the closures section with major expansion --- examples/{fn => attribute}/unused/input.md | 0 examples/{fn => attribute}/unused/unused.rs | 0 examples/fn/closures/anonymity/anonymity.rs | 18 +++++++ examples/fn/closures/anonymity/input.md | 34 ++++++++++++ examples/fn/closures/capture/capture.rs | 52 +++++++++++++++++++ examples/fn/closures/capture/input.md | 20 +++++++ .../fn/closures/closure_analysis/input.md | 1 + .../closure_analysis/iter_any/input.md | 26 ++++++++++ .../closure_analysis/iter_any/iter_any.rs | 17 ++++++ .../closure_analysis/iter_find/input.md | 26 ++++++++++ .../closure_analysis/iter_find/iter_find.rs | 22 ++++++++ examples/fn/closures/closures.rs | 34 +++++++++--- examples/fn/closures/input.md | 18 ++++--- examples/fn/closures/input_functions/input.md | 16 ++++++ .../input_functions/input_functions.rs | 9 ++++ .../fn/closures/input_parameters/input.md | 22 ++++++++ .../input_parameters/input_parameters.rs | 45 ++++++++++++++++ .../fn/closures/output_parameters/input.md | 26 ++++++++++ .../output_parameters/output_parameters.rs | 30 +++++++++++ examples/structure.json | 14 ++++- 20 files changed, 414 insertions(+), 16 deletions(-) rename examples/{fn => attribute}/unused/input.md (100%) rename examples/{fn => attribute}/unused/unused.rs (100%) create mode 100644 examples/fn/closures/anonymity/anonymity.rs create mode 100644 examples/fn/closures/anonymity/input.md create mode 100644 examples/fn/closures/capture/capture.rs create mode 100644 examples/fn/closures/capture/input.md create mode 100644 examples/fn/closures/closure_analysis/input.md create mode 100644 examples/fn/closures/closure_analysis/iter_any/input.md create mode 100644 examples/fn/closures/closure_analysis/iter_any/iter_any.rs create mode 100644 examples/fn/closures/closure_analysis/iter_find/input.md create mode 100644 examples/fn/closures/closure_analysis/iter_find/iter_find.rs create mode 100644 examples/fn/closures/input_functions/input.md create mode 100644 examples/fn/closures/input_functions/input_functions.rs create mode 100644 examples/fn/closures/input_parameters/input.md create mode 100644 examples/fn/closures/input_parameters/input_parameters.rs create mode 100644 examples/fn/closures/output_parameters/input.md create mode 100644 examples/fn/closures/output_parameters/output_parameters.rs diff --git a/examples/fn/unused/input.md b/examples/attribute/unused/input.md similarity index 100% rename from examples/fn/unused/input.md rename to examples/attribute/unused/input.md diff --git a/examples/fn/unused/unused.rs b/examples/attribute/unused/unused.rs similarity index 100% rename from examples/fn/unused/unused.rs rename to examples/attribute/unused/unused.rs diff --git a/examples/fn/closures/anonymity/anonymity.rs b/examples/fn/closures/anonymity/anonymity.rs new file mode 100644 index 0000000000..c3f6f93624 --- /dev/null +++ b/examples/fn/closures/anonymity/anonymity.rs @@ -0,0 +1,18 @@ +// `F` must implement `Fn` for a function which takes no +// inputs and returns nothing. Exactly what is required +// for `diary`. +fn apply(f: F) where + F: Fn() { + + f() +} + +fn main() { + let x = 7; + + // Capture `x` into an anonymous type and implement + // `Fn` for it. Store it in `print`. + let print = || println!("{}", x); + + apply(print); +} diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md new file mode 100644 index 0000000000..ad42294b6b --- /dev/null +++ b/examples/fn/closures/anonymity/input.md @@ -0,0 +1,34 @@ +Closures are supposedly anonymous. Does that affect it's usage? It surely +does. Observe how using a closure in a function requires generics, which +is necessary because of how they are defined: + +```rust +// `F` must be generic. +fn apply(f: F) where + F: FnOnce() { + f() +} +``` + +When a closure is defined, the compiler implicitly creates a new +anonymous structure to store the captured variables inside, meanwhile +implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` for this unknown type. This type is assigned to the variable which +is stored until calling. + +Since this new type is of unknown type, any usage in a function will require +generics. However, an unbounded type parameter (``) would still be ambiguous +and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` (which it implements) is sufficient to specify it's type. + +{anonymity.play} + +### See also: + +[A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], +and [`FnOnce`][fn_once] + +[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html +[thorough_analysis]: http://huonw.github.io/blog/2015/05/finding-closure-in-rust/ diff --git a/examples/fn/closures/capture/capture.rs b/examples/fn/closures/capture/capture.rs new file mode 100644 index 0000000000..a5045d7ea2 --- /dev/null +++ b/examples/fn/closures/capture/capture.rs @@ -0,0 +1,52 @@ +fn main() { + let color = "green"; + + // A closure to print `color` which immediately borrows (`&`) + // `color` and stores the borrow and closure in the `print` + // variable. It will remain borrowed until `print` goes out of + // scope. `println!` only requires `by reference` so it doesn't + // impose anything more restrictive. + let print = || println!("`color`: {}", color); + + // Call the closure using the borrow. + print(); + print(); + + let mut count = 0; + + // A closure to increment `count` could take either `&mut count` + // or `count` but `&mut count` is less restrictive so it takes + // that. Immediately borrows `count`. + // + // A `mut` is required on `inc` because a `&mut` is stored inside. + // Thus, calling the closure mutates the closure which requires + // a `mut`. + let mut inc = || { + count += 1; + println!("`count`: {}", count); + }; + + // Call the closure. + inc(); + inc(); + + //let reborrow = &mut count; + // ^ TODO: try uncommenting this line. + + // A non-copy type. + let movable = Box::new(3); + + // `drop` requires `T` so this must take by value. A copy type + // would copy into the closure leaving the original untouched. + // A non-copy must move and so `movable` immediately moves into + // the closure. + let consume = || { + println!("`movable`: {:?}", movable); + drop(movable); + }; + + // `eat` consumes the variable so this can only be called once. + consume(); + //consume(); + // ^ TODO: Try uncommenting this line. +} diff --git a/examples/fn/closures/capture/input.md b/examples/fn/closures/capture/input.md new file mode 100644 index 0000000000..0655dcee8a --- /dev/null +++ b/examples/fn/closures/capture/input.md @@ -0,0 +1,20 @@ +Closures are inherently flexible and will do what the functionality requires +to make the closure work without annotation. This allows capturing to +flexibly adapt to the use case, sometimes moving and sometimes borrowing. +Closures can capture variables: + +* by reference: `&T` +* by mutable reference: `&mut T` +* by value: `T` + +They preferentially capture variables by reference and only go lower when +required. + +{capture.play} + +### See also: + +[`Box`][box] and [`std::mem::drop`][drop] + +[box]: /std/box.html +[drop]: http://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/examples/fn/closures/closure_analysis/input.md b/examples/fn/closures/closure_analysis/input.md new file mode 100644 index 0000000000..90e12b7ae9 --- /dev/null +++ b/examples/fn/closures/closure_analysis/input.md @@ -0,0 +1 @@ +A brief analysis of a few different `std` library closure examples. diff --git a/examples/fn/closures/closure_analysis/iter_any/input.md b/examples/fn/closures/closure_analysis/iter_any/input.md new file mode 100644 index 0000000000..59c3516f9e --- /dev/null +++ b/examples/fn/closures/closure_analysis/iter_any/input.md @@ -0,0 +1,26 @@ +`Iterator::any` is a function which when passed an iterator, will return +`true` if any element satisfies the predicate. Otherwise `false`. It's +signature: + +```rust +pub trait Iterator { + // The type being iterated over. + type Item; + + // `any` takes `&mut self` meaning the caller may be borrowed + // and modified, but not consumed. + fn any(&mut self, f: F) -> bool where + // `FnMut` meaning any captured variable may at most be + // modified, not consumed. `Self::Item` states it takes + // arguments to the closure by value. + F: FnMut(Self::Item) -> bool {} +} +``` + +{iter_any.play} + +### See also: + +[`Iterator::any`][any] + +[any]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/examples/fn/closures/closure_analysis/iter_any/iter_any.rs b/examples/fn/closures/closure_analysis/iter_any/iter_any.rs new file mode 100644 index 0000000000..349ab12f1f --- /dev/null +++ b/examples/fn/closures/closure_analysis/iter_any/iter_any.rs @@ -0,0 +1,17 @@ +fn main() { + let vec1 = vec![1, 2, 3]; + let vec2 = vec![4, 5, 6]; + + // `iter` yields `&i32`. Destructure to `i32`. + println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); + // `into_iter` yields `i32`. No destructuring required. + println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2)); + + let array1 = [1, 2, 3]; + let array2 = [4, 5, 6]; + + // `iter()` is normal. `into_iter()` for arrays unusually + // yields `&i32`. These would not normally both be `&`. + println!("2 in array1: {}", array1.iter() .any(|&x| x == 2)); + println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2)); +} diff --git a/examples/fn/closures/closure_analysis/iter_find/input.md b/examples/fn/closures/closure_analysis/iter_find/input.md new file mode 100644 index 0000000000..895f439b9d --- /dev/null +++ b/examples/fn/closures/closure_analysis/iter_find/input.md @@ -0,0 +1,26 @@ +`Iterator::find` is a function which when passed an iterator, will return +the first element which satisfies the predicate as an `Option`. It's +signature: + +```rust +pub trait Iterator { + // The type being iterated over. + type Item; + + // `any` takes `&mut self` meaning the caller may be borrowed + // and modified, but not consumed. + fn find

(&mut self, predicate: P) -> Option where + // `FnMut` meaning any captured variable may at most be + // modified, not consumed. `&Self::Item` states it takes + // arguments to the closure by reference. + P: FnMut(&Self::Item) -> bool {} +} +``` + +{iter_find.play} + +### See also: + +[`Iterator::find`][find] + +[find]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/examples/fn/closures/closure_analysis/iter_find/iter_find.rs b/examples/fn/closures/closure_analysis/iter_find/iter_find.rs new file mode 100644 index 0000000000..01b0c605bd --- /dev/null +++ b/examples/fn/closures/closure_analysis/iter_find/iter_find.rs @@ -0,0 +1,22 @@ +fn main() { + let vec1 = vec![1, 2, 3]; + let vec2 = vec![4, 5, 6]; + + // `iter()` yields `&i32`. `into_iter()` yields `i32`. + let mut iter = vec1.iter(); + let mut into_iter = vec2.into_iter(); + + // A reference to what is yielded is `&&i32`. Destructure to `i32`. + println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2)); + // A reference to what is yielded is `&i32`. Destructure to `i32`. + println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2)); + + let array1 = [1, 2, 3]; + let array2 = [4, 5, 6]; + + // `iter()` is normal. `into_iter()` for arrays unusually + // yields `&i32`. These would not normally both be `&&`. + println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2)); + println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2)); +} + diff --git a/examples/fn/closures/closures.rs b/examples/fn/closures/closures.rs index c41311488b..6f49304958 100644 --- a/examples/fn/closures/closures.rs +++ b/examples/fn/closures/closures.rs @@ -1,12 +1,32 @@ fn main() { - let captured_value = 7u32; + // Increment via closures and functions. + fn function (i: i32) -> i32 { i + 1 } - let closure = |argument| { - println!("I captured this: {}", captured_value); - println!("Argument passed was: {}", argument); + // Annotation is identical to function annotation but is optional + // as are the `{}` wrapping the body. These nameless functions + // are assigned to appropriately named variables. + let closure_annotated = |i: i32| -> i32 { i + 1 }; + let closure_inferred = |i | i + 1 ; - true - }; + let i = 1; + // Call the function and closures. + println!("function: {}", function(i)); + println!("annotated closure: {}", closure_annotated(i)); + println!("inferred closure: {}", closure_inferred(i)); - println!("Closure returned: {}", closure("a string")); + // A closure taking no arguments which returns an `i32`. + // The return type is inferred. + let one = || 1; + println!("closure returning one: {}", one()); + + // It is possible to capture variables from the enclosing + // environment; something which is impossible with functions. + let professor_x = "Charles Xavier"; + + // A closure which takes no argument, returning nothing, prints + // a variable from the enclosing scope. + let print = || println!("Professor X's name is: {}", professor_x); + + // Call the closure. + print(); } diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 55685fbb48..3468f3105c 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -1,10 +1,14 @@ -Closures are special functions that can capture the variables available in the -surrounding scope. Closures consist of three parts: +Closures[^*] in Rust are functions with a slightly specialized syntax which +can capture the enclosing environment. Their syntax and capabilties make them +very convenient for on the fly usage. Some characteristics include: -* A list of arguments enclosed by pipes `|`. These arguments can optionally be - type annotated, but usually the compiler will infer their types -* Optionally the return type using an arrow `->`. Again, this usually gets - inferred -* A block. The last expression is the return value +* uses `||` instead of `()` around input variables. +* *both* input and return types can be inferred. +* body delimination (`{}`) is optional for a single expression. Mandatory +otherwise. +* the outer environment variables *may* be captured. +* calling a closure is exactly like a function: `call(var)`. {closures.play} + +[^*]: Also called `lambdas` or `anonymous functions`. diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md new file mode 100644 index 0000000000..e0aa3c2218 --- /dev/null +++ b/examples/fn/closures/input_functions/input.md @@ -0,0 +1,16 @@ +Since closures are possible as arguments, you might wonder if functions +are also possible and indeed they are. The previously mentioned `Fn`, +`FnMut`, and `FnOnce` `traits` all dictate what fashion a closure captures +variables from the enclosing scope. A function can *never* capture variables +and thus is strictly less flexible. Therefore, any function which can +take a closure as an argument can also take a function. + +{input_functions.play} + +### See also: + +[`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] + +[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs new file mode 100644 index 0000000000..2392d1950d --- /dev/null +++ b/examples/fn/closures/input_functions/input_functions.rs @@ -0,0 +1,9 @@ +fn call_function(f: F) { + f() +} + +fn print() { println!("I'm a function!") } + +fn main() { + call_function(print); +} diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md new file mode 100644 index 0000000000..95d15c8b0a --- /dev/null +++ b/examples/fn/closures/input_parameters/input.md @@ -0,0 +1,22 @@ +It has been noted that Rust chooses how to capture variable on the fly +without annotation. This is all very convenient in normal usage however when +writing functions, this ambiguity is not allowed. The closure's complete +type including which capturing type must be annotated. The manner of capture +a closure uses is annotated as one of the following `traits`: + +* `Fn`: takes captures by reference (`&T`) +* `FnMut`: takes captures by mutable reference (`&mut T`) +* `FnOnce`: take captures by value (`T`) + +Even annotated, these are very flexible: a parameter of `FnOnce` specifies +the closure *may* capture by `T` or `&mut T` or `&T` at will (if a move is +possible, any type of borrow should also be possible). The reverse is not +true: if the parameter is `Fn`, then nothing lower is allowed. Therefore, +the rule is: + +* any annotated parameter restricts capture to itself and above + +In addition, Rust will preferentially capture variables in the least +restrictive manner possible on a variable-by-variable basis: + +{input_parameters.play} diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs new file mode 100644 index 0000000000..e0dba5bf93 --- /dev/null +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -0,0 +1,45 @@ +// A function which takes a closure as an argument and calls +// it. The closure takes no input and returns nothing. +fn apply(f: F) where + F: FnOnce() { + // ^ TODO: Try changing this to `Fn` or `FnMut`. + + f() +} + +// A function which takes a closure and returns an `i32`. +fn apply_to_3(f: F) -> i32 where + // The closure takes an `i32` and returns an `i32`. + F: Fn(i32) -> i32 { + + f(3) +} + +fn main() { + let greeting = "hello"; + let mut farewell = "goodbye".to_owned(); + + // Capture 2 variables: `greeting` by reference and + // `farewell` by value. + let diary = || { + // `greeting` is by reference: requires `Fn`. + println!("I said {}.", greeting); + + // Mutation forces `farewell` to be captured by + // mutable reference. Now requires `FnMut`. + farewell.push_str("!!!"); + println!("Then I screamed {}.", farewell); + println!("Now I can sleep. zzzzz"); + + // Manually calling drop forces `farewell` to + // be captured by value. Now requires `FnOnce`. + drop(farewell); + }; + + // Call the function which applies the closure. + apply(diary); + + let double = |x| 2 * x; + + println!("3 doubled: {}", apply_to_3(double)); +} diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md new file mode 100644 index 0000000000..6f2527c040 --- /dev/null +++ b/examples/fn/closures/output_parameters/input.md @@ -0,0 +1,26 @@ +Closures as input parameters are possible so returning one should also be +possible. However, returning closure types are problematic because Rust +currently only supports returning concrete (non-generic) types. Anonymous +closure types are, by definition, unknown and so returning a closure is only +possible by making it concrete. This can be done via boxing. + +The valid types for returns are slightly different than before: + +* `Fn`: normal +* `FnMut`: normal +* `FnBox`: equivalent to `FnOnce` but specialized for this application +because `FnOnce` currently interacts badly with the type system. + +Beyond this, the `move` keyword must be used which signals that all captures +occur by value. This is required because any captures by reference would be +dropped as soon as the function exited leaving invalid references in the +closure. + +{output_parameters.play} + +### See also: + +[Boxing][box] and [Generics][generics] + +[box]: /std/box.html +[generics]: /generics.html diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs new file mode 100644 index 0000000000..7d2fcab56e --- /dev/null +++ b/examples/fn/closures/output_parameters/output_parameters.rs @@ -0,0 +1,30 @@ +#![feature(core)] +use std::boxed::FnBox; + +fn create_fnbox() -> Box { + let text = "FnBox".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn create_fn() -> Box { + let text = "Fn".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn create_fnmut() -> Box { + let text = "FnMut".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn main() { + let fn_plain = create_fn(); + let mut fn_mut = create_fnmut(); + let fn_box = create_fnbox(); + + fn_plain(); + fn_mut(); + fn_box(); +} diff --git a/examples/structure.json b/examples/structure.json index 4cbef9d583..bceb2c208a 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -55,9 +55,18 @@ { "id": "while_let", "title": "while let", "children": null } ] }, { "id": "fn", "title": "Functions", "children": [ - { "id": "unused", "title": "Unused", "children": null }, { "id": "methods", "title": "Methods", "children": null }, - { "id": "closures", "title": "Closures", "children": null }, + { "id": "closures", "title": "Closures", "children": [ + { "id": "capture", "title": "Capturing", "children": null }, + { "id": "input_parameters", "title": "As input parameters", "children": null }, + { "id": "anonymity", "title": "Anonymity", "children": null }, + { "id": "input_functions", "title": "Input functions", "children": null }, + { "id": "output_parameters", "title": "As output parameters", "children": null }, + { "id": "closure_analysis", "title": "Analysis", "children": [ + { "id": "iter_any", "title": "Iterator::any", "children": null }, + { "id": "iter_find", "title": "Iterator::find", "children": null } + ] } + ] }, { "id": "hof", "title": "Higher Order Functions", "children": null } ] }, { "id": "macros", "title": "macro_rules!", "children": [ @@ -77,6 +86,7 @@ { "id": "link", "title": "`extern crate`", "children": null } ] }, { "id": "attribute", "title": "Attributes", "children": [ + { "id": "unused", "title": "Unused", "children": null }, { "id": "crate", "title": "Crates", "children": null }, { "id": "cfg", "title": "`cfg`", "children": [ { "id": "custom", "title": "Custom", "children": null } From a7139715f3eaadd0ae9431e4835d7d23e793629a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 14 Jun 2015 17:40:04 -0300 Subject: [PATCH 0284/1122] GenTup is not a tuple so name it as GenVal --- examples/generics/impl/impl.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/generics/impl/impl.rs b/examples/generics/impl/impl.rs index a8fbde66f7..5587246380 100644 --- a/examples/generics/impl/impl.rs +++ b/examples/generics/impl/impl.rs @@ -1,19 +1,19 @@ -struct Tup (f64,); -struct GenTup(T,); +struct Val (f64,); +struct GenVal(T,); -// impl of Tup -impl Tup { +// impl of Val +impl Val { fn value(&self) -> &f64 { &self.0 } } -// impl of GenTup for a generic type `T` -impl GenTup { +// impl of GenVal for a generic type `T` +impl GenVal { fn value(&self) -> &T { &self.0 } } fn main() { - let x = Tup(3.0); - let y = GenTup(3i32); + let x = Val(3.0); + let y = GenVal(3i32); println!("{}, {}", x.value(), y.value()); } From 765e95ca4d18a0598a73ac2b57089859e0ac15fe Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 14 Jun 2015 18:12:19 -0300 Subject: [PATCH 0285/1122] GenericTup is not a tuple so name it as GenericVal --- examples/generics/impl/input.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 3382094733..e8426b03d3 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -2,14 +2,14 @@ Similar to functions, implementations require care to remain generic. ```rust struct S; // A null struct -struct GenericTup(T,); +struct GenericVal(T,); -// impl of GenericTup we specifically specialize: -impl GenericTup {} // Specialize to `f32` -impl GenericTup {} // Specialize to `S` defined above +// impl of GenericVal we specifically specialize: +impl GenericVal {} // Specialize to `f32` +impl GenericVal {} // Specialize to `S` defined above // `` Must precede the type to remain generic -impl GenericTup {} +impl GenericVal {} ``` Note: Rust does not *currently* allow overlap between implementations. The From 044a6aaa4dac3573fa85cbd2c5a15f88a999ef76 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 15 Jun 2015 12:42:27 -0400 Subject: [PATCH 0286/1122] A couple tweaks --- examples/fn/closures/anonymity/anonymity.rs | 4 ++-- examples/fn/closures/anonymity/input.md | 6 +++--- examples/fn/closures/input.md | 3 ++- examples/fn/closures/input_parameters/input_parameters.rs | 1 + examples/fn/closures/output_parameters/output_parameters.rs | 2 ++ examples/structure.json | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/fn/closures/anonymity/anonymity.rs b/examples/fn/closures/anonymity/anonymity.rs index c3f6f93624..c09e260468 100644 --- a/examples/fn/closures/anonymity/anonymity.rs +++ b/examples/fn/closures/anonymity/anonymity.rs @@ -1,6 +1,6 @@ -// `F` must implement `Fn` for a function which takes no +// `F` must implement `Fn` for a closure which takes no // inputs and returns nothing. Exactly what is required -// for `diary`. +// for `print`. fn apply(f: F) where F: Fn() { diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index ad42294b6b..7dc8410d34 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -1,6 +1,6 @@ -Closures are supposedly anonymous. Does that affect it's usage? It surely -does. Observe how using a closure in a function requires generics, which -is necessary because of how they are defined: +Closures succinctly capture variables from enclosing scopes. Does this have +any consequences? It surely does. Observe how using a closure in a function +requires generics, which is necessary because of how they are defined: ```rust // `F` must be generic. diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 3468f3105c..3ddbe60652 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -3,7 +3,8 @@ can capture the enclosing environment. Their syntax and capabilties make them very convenient for on the fly usage. Some characteristics include: * uses `||` instead of `()` around input variables. -* *both* input and return types can be inferred. +* *both* input and return *types* can be inferred. +* input variable *names* must be specified. * body delimination (`{}`) is optional for a single expression. Mandatory otherwise. * the outer environment variables *may* be captured. diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs index e0dba5bf93..339f49d6a2 100644 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -17,6 +17,7 @@ fn apply_to_3(f: F) -> i32 where fn main() { let greeting = "hello"; + // A non-copy type. let mut farewell = "goodbye".to_owned(); // Capture 2 variables: `greeting` by reference and diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs index 7d2fcab56e..de2f3c8fea 100644 --- a/examples/fn/closures/output_parameters/output_parameters.rs +++ b/examples/fn/closures/output_parameters/output_parameters.rs @@ -1,6 +1,8 @@ #![feature(core)] use std::boxed::FnBox; +// Return a closure taking no inputs and returning nothing +// which implements `FnBox` (capture by value). fn create_fnbox() -> Box { let text = "FnBox".to_owned(); diff --git a/examples/structure.json b/examples/structure.json index bceb2c208a..7b44b48c27 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -59,7 +59,7 @@ { "id": "closures", "title": "Closures", "children": [ { "id": "capture", "title": "Capturing", "children": null }, { "id": "input_parameters", "title": "As input parameters", "children": null }, - { "id": "anonymity", "title": "Anonymity", "children": null }, + { "id": "anonymity", "title": "Type anonymity", "children": null }, { "id": "input_functions", "title": "Input functions", "children": null }, { "id": "output_parameters", "title": "As output parameters", "children": null }, { "id": "closure_analysis", "title": "Analysis", "children": [ From db16b9ce0246cffc5ed1ebdeda1d2ee019dbaa22 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 15 Jun 2015 12:43:28 -0400 Subject: [PATCH 0287/1122] Add more links --- examples/fn/closures/input_parameters/input.md | 9 +++++++++ examples/fn/closures/output_parameters/input.md | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md index 95d15c8b0a..868d96ac35 100644 --- a/examples/fn/closures/input_parameters/input.md +++ b/examples/fn/closures/input_parameters/input.md @@ -20,3 +20,12 @@ In addition, Rust will preferentially capture variables in the least restrictive manner possible on a variable-by-variable basis: {input_parameters.play} + +### See also: + +[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce] + +[drop]: http://doc.rust-lang.org/std/mem/fn.drop.html +[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnonce]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index 6f2527c040..0144555114 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -20,7 +20,11 @@ closure. ### See also: -[Boxing][box] and [Generics][generics] +[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], [`FnBox`][fnbox], and +[Generics][generics] [box]: /std/box.html +[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnbox]: http://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: /generics.html From 523eff5a5905c8ca2c0a8c5579bd9b5e85727c26 Mon Sep 17 00:00:00 2001 From: John Berry Date: Fri, 19 Jun 2015 20:27:56 +0300 Subject: [PATCH 0288/1122] Fix warning: deprecated item This sample throws a warning in line 36 currently, which does not appear to be intended: ``` warning: use of deprecated item: use `String::from` instead, #[warn(deprecated)] on by default ``` As making the suggested change produces this warning instead: ``` warning: unused or unknown feature, #[warn(unused_features)] on by default ``` ...the reference to `#![feature(collections)]` is removed as well. --- examples/std/str/str.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/std/str/str.rs b/examples/std/str/str.rs index af2bb6720d..7b88acb5bc 100644 --- a/examples/std/str/str.rs +++ b/examples/std/str/str.rs @@ -1,5 +1,3 @@ -#![feature(collections)] - fn main() { // (all the type annotations are superfluous) // A reference to a string allocated in read only memory @@ -33,7 +31,7 @@ fn main() { println!("Used characters: {}", trimmed_str); // Heap allocate a string - let alice = String::from_str("I like dogs"); + let alice = String::from("I like dogs"); // Allocate new memory and store the modified string there let bob: String = alice.replace("dog", "cat"); From 6f4efccba69bcb60468bdf9793773c360445f9fa Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 19 Jun 2015 16:09:33 -0400 Subject: [PATCH 0289/1122] Fix the build Fixes #599 --- .../fn/closures/output_parameters/output_parameters.rs | 3 ++- examples/fn/hof/hof.rs | 2 +- examples/std_misc/arg/args.rs | 2 +- examples/std_misc/arg/getopts/echo.rs | 7 +++---- examples/std_misc/arg/getopts/testopt.rs | 9 ++++----- examples/std_misc/simd/simd.rs | 2 +- examples/std_misc/simd/simd_add.rs | 2 +- src/main.rs | 3 ++- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs index de2f3c8fea..5452cb4f12 100644 --- a/examples/fn/closures/output_parameters/output_parameters.rs +++ b/examples/fn/closures/output_parameters/output_parameters.rs @@ -1,4 +1,5 @@ -#![feature(core)] +#![feature(fnbox)] + use std::boxed::FnBox; // Return a closure taking no inputs and returning nothing diff --git a/examples/fn/hof/hof.rs b/examples/fn/hof/hof.rs index ba2edd7337..592cfea45d 100644 --- a/examples/fn/hof/hof.rs +++ b/examples/fn/hof/hof.rs @@ -1,4 +1,4 @@ -#![feature(core)] +#![feature(iter_arith)] fn main() { println!("Find the sum of all the squared odd numbers under 1000"); diff --git a/examples/std_misc/arg/args.rs b/examples/std_misc/arg/args.rs index 647583b471..0d399076d4 100644 --- a/examples/std_misc/arg/args.rs +++ b/examples/std_misc/arg/args.rs @@ -1,4 +1,4 @@ -#![feature(collections)] +#![feature(slice_extras)] use std::env; diff --git a/examples/std_misc/arg/getopts/echo.rs b/examples/std_misc/arg/getopts/echo.rs index c004d94f34..c115f4b1a1 100644 --- a/examples/std_misc/arg/getopts/echo.rs +++ b/examples/std_misc/arg/getopts/echo.rs @@ -1,12 +1,12 @@ #![feature(rustc_private)] -#![feature(collections)] -#![feature(exit_status)] +#![feature(slice_extras)] extern crate getopts; use std::env; use std::io; use std::io::Write; +use std::process; static VERSION: &'static str = "1.0.0"; @@ -29,8 +29,7 @@ fn main() { Ok(m) => m, Err(f) => { println!("{}", f); - env::set_exit_status(1); - return; + process::exit(1); // The exit code is 0 (success) by default. // Any exit code other than 0 indicates failure. } diff --git a/examples/std_misc/arg/getopts/testopt.rs b/examples/std_misc/arg/getopts/testopt.rs index da40ab5a2e..cfe7c0a431 100644 --- a/examples/std_misc/arg/getopts/testopt.rs +++ b/examples/std_misc/arg/getopts/testopt.rs @@ -1,10 +1,10 @@ #![feature(rustc_private)] -#![feature(collections)] -#![feature(exit_status)] +#![feature(slice_extras)] extern crate getopts; use std::env; +use std::process; fn main() { let args: Vec = env::args().collect(); @@ -22,15 +22,14 @@ fn main() { Ok(m) => m, Err(f) => { println!("{}", f); - env::set_exit_status(1); - return; + process::exit(1); } }; let a = if matches.opt_present("a") {true} else {false}; let b = if matches.opt_present("b") {true} else {false}; let c = match matches.opt_str("c") { Some(s) => s, - None => String::from_str(""), + None => String::from(""), }; //^ Use `matches.opt_default` if you need a default (`opflagopt`). // Use `matches.opt_count` if you need to count how many were matched diff --git a/examples/std_misc/simd/simd.rs b/examples/std_misc/simd/simd.rs index bdc8c2491c..144f8f4e5e 100644 --- a/examples/std_misc/simd/simd.rs +++ b/examples/std_misc/simd/simd.rs @@ -1,4 +1,4 @@ -#![feature(core)] +#![feature(core_simd)] use std::simd::f32x4; diff --git a/examples/std_misc/simd/simd_add.rs b/examples/std_misc/simd/simd_add.rs index 4f225fd36c..71eeb5863f 100644 --- a/examples/std_misc/simd/simd_add.rs +++ b/examples/std_misc/simd/simd_add.rs @@ -1,5 +1,5 @@ #![feature(test)] -#![feature(core)] +#![feature(core_simd)] use std::simd::f32x4; diff --git a/src/main.rs b/src/main.rs index 86ba682b6f..cc45f0056c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ -#![feature(core)] +#![feature(iter_arith)] #![feature(scoped)] #![deny(warnings)] +#![allow(deprecated)] // thread::scoped needs to go, but can't do it now #![feature(plugin)] extern crate regex; From 81b8e291721c324c8343621a2d9d1d7b02418434 Mon Sep 17 00:00:00 2001 From: Cornel Punga Date: Wed, 24 Jun 2015 09:21:35 +0300 Subject: [PATCH 0290/1122] Update methods perimeter expression In my opinion this version is more readable, also theoretically faster. --- examples/fn/methods/methods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/methods/methods.rs b/examples/fn/methods/methods.rs index 599ee4c469..26c803a663 100644 --- a/examples/fn/methods/methods.rs +++ b/examples/fn/methods/methods.rs @@ -41,7 +41,7 @@ impl Rectangle { let Point { x: x1, y: y1 } = self.p1; let Point { x: x2, y: y2 } = self.p2; - 2.0 * (x1 - x2).abs() + 2.0 * (y1 - y2).abs() + 2.0 * ((x1 - x2).abs() + (y1 - y2).abs()) } // This method requires the caller object to be mutable From f0f86a1aac5f6c62c124615ac66fb34f557229b2 Mon Sep 17 00:00:00 2001 From: Sergei Mironenko Date: Wed, 24 Jun 2015 14:02:31 +0300 Subject: [PATCH 0291/1122] generics/impl: fix typo --- examples/generics/impl/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index e8426b03d3..9ad3b2bfc4 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -13,7 +13,7 @@ impl GenericVal {} ``` Note: Rust does not *currently* allow overlap between implementations. The -3 separate implementations of `GenericTup` above cannot coexist. There are +3 separate implementations of `GenericVal` above cannot coexist. There are [plans][specialization_plans] to fix this though. {impl.play} From bc65eeb07acda427a19332408b407379222a19c0 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 24 Jun 2015 14:10:33 -0400 Subject: [PATCH 0292/1122] Suppress warnings on cast by default --- examples/cast/cast.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/cast/cast.rs b/examples/cast/cast.rs index cb6b0139e4..4d5f44fb6e 100644 --- a/examples/cast/cast.rs +++ b/examples/cast/cast.rs @@ -1,3 +1,6 @@ +// Suppress all warnings from casts which overflow. +#![allow(overflowing_literals)] + fn main() { let decimal = 65.4321_f32; From cab9035f51457c8a4f0bfb34a066c888775b5091 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 25 Jun 2015 21:48:09 -0400 Subject: [PATCH 0293/1122] Move visibility --- .../structs/visibility => mod/struct_visibility}/input.md | 0 .../structs/visibility => mod/struct_visibility}/struct.rs | 0 examples/structure.json | 5 ++--- 3 files changed, 2 insertions(+), 3 deletions(-) rename examples/{custom_types/structs/visibility => mod/struct_visibility}/input.md (100%) rename examples/{custom_types/structs/visibility => mod/struct_visibility}/struct.rs (100%) diff --git a/examples/custom_types/structs/visibility/input.md b/examples/mod/struct_visibility/input.md similarity index 100% rename from examples/custom_types/structs/visibility/input.md rename to examples/mod/struct_visibility/input.md diff --git a/examples/custom_types/structs/visibility/struct.rs b/examples/mod/struct_visibility/struct.rs similarity index 100% rename from examples/custom_types/structs/visibility/struct.rs rename to examples/mod/struct_visibility/struct.rs diff --git a/examples/structure.json b/examples/structure.json index 7b44b48c27..605152a91d 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -15,9 +15,7 @@ { "id": "array", "title": "Arrays and Slices", "children": null } ] }, { "id": "custom_types", "title": "Custom types", "children": [ - { "id": "structs", "title": "Structures", "children": [ - { "id": "visibility", "title": "Visibility", "children": null } - ] }, + { "id": "structs", "title": "Structures", "children": null }, { "id": "enum", "title": "Enums", "children": [ { "id": "c_like", "title": "C-like", "children": null } ] }, @@ -77,6 +75,7 @@ ] }, { "id": "mod", "title": "Modules", "children": [ { "id": "visibility", "title": "Visibility", "children": null }, + { "id": "struct_visibility", "title": "Struct visibility", "children": null }, { "id": "use", "title": "The `use` declaration", "children": null }, { "id": "super", "title": "`super` and `self`", "children": null }, { "id": "split", "title": "File hierarchy", "children": null } From cedb0d8573415cfcce376fa221e4b79c3c145e63 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 26 Jun 2015 01:10:23 -0400 Subject: [PATCH 0294/1122] Simplify enum examples. Move linked list to a testcase. --- examples/custom_types/enum/c_like/c_like.rs | 46 ++------- examples/custom_types/enum/c_like/input.md | 6 ++ examples/custom_types/enum/enum.rs | 97 +++++++------------ examples/custom_types/enum/enum_use/input.md | 10 ++ examples/custom_types/enum/enum_use/use.rs | 36 +++++++ examples/custom_types/enum/input.md | 18 ++-- .../enum/testcase_linked_list/input.md | 10 ++ .../enum/testcase_linked_list/linked_list.rs | 66 +++++++++++++ examples/custom_types/structs/input.md | 6 ++ examples/structure.json | 4 +- 10 files changed, 195 insertions(+), 104 deletions(-) create mode 100644 examples/custom_types/enum/enum_use/input.md create mode 100644 examples/custom_types/enum/enum_use/use.rs create mode 100644 examples/custom_types/enum/testcase_linked_list/input.md create mode 100644 examples/custom_types/enum/testcase_linked_list/linked_list.rs diff --git a/examples/custom_types/enum/c_like/c_like.rs b/examples/custom_types/enum/c_like/c_like.rs index ec7afa53c2..a0bf6faf15 100644 --- a/examples/custom_types/enum/c_like/c_like.rs +++ b/examples/custom_types/enum/c_like/c_like.rs @@ -1,41 +1,14 @@ -// If you'd like to refer to the days without saying -// `Day::Monday`, then you use the following notation -// use Day::{ -// Monday, -// Tuesday, -// Wednesday, -// Thursday, -// Friday, -// Saturday, -// Sunday, -// } -// -// And you can refer to enum variants just like in C +// An attribute to hide warnings for unused code. +#![allow(dead_code)] // enum with implicit discriminator (starts at 0) -#[allow(dead_code)] -enum Day { - Monday, - Tuesday, - Wednesday, - Thursday, - Friday, - Saturday, - Sunday, -} - -impl Day { - fn mood(&self) { - println!("{}", match *self { - Day::Friday => "it's friday!", - Day::Saturday | Day::Sunday => "weekend :-)", - _ => "weekday...", - }) - } +enum Number { + Zero, + One, + Two, } // enum with explicit discriminator -#[allow(dead_code)] enum Color { Red = 0xff0000, Green = 0x00ff00, @@ -43,11 +16,10 @@ enum Color { } fn main() { - let today = Day::Monday; - - today.mood(); + // `enums` can be cast as integers. + println!("zero is {}", Number::Zero as i32); + println!("one is {}", Number::One as i32); - // enums can be casted into integers println!("roses are #{:06x}", Color::Red as i32); println!("violets are #{:06x}", Color::Blue as i32); } diff --git a/examples/custom_types/enum/c_like/input.md b/examples/custom_types/enum/c_like/input.md index 02bc0a2845..019e0148d7 100644 --- a/examples/custom_types/enum/c_like/input.md +++ b/examples/custom_types/enum/c_like/input.md @@ -1,3 +1,9 @@ `enum` can also be used as C-like enums. {c_like.play} + +### See also: + +[casting][cast] + +[cast]: /cast.html diff --git a/examples/custom_types/enum/enum.rs b/examples/custom_types/enum/enum.rs index 43c161afe4..361f82eb87 100644 --- a/examples/custom_types/enum/enum.rs +++ b/examples/custom_types/enum/enum.rs @@ -1,68 +1,45 @@ -// Allow Cons and Nil to be referred to without namespacing -use List::{Cons, Nil}; - -// A linked list node, which can take on any of these two variants -enum List { - // Cons: Tuple struct that wraps an element and a pointer to the next node - Cons(u32, Box), - // Nil: A node that signifies the end of the linked list - Nil, +// An attribute to hide warnings for unused code. +#![allow(dead_code)] + +// Create an `enum` to classify someone. Note how both names +// and type information together specify the variant: +// `Skinny != Fat` and `Height(i32) != Weight(i32)`. Each +// is different and independent. +enum Person { + // An `enum` may either be `unit-like`, + Skinny, + Fat, + // like tuple structs, + Height(i32), + Weight(i32), + // or like structures. + Info { name: String, height: i32 } } -// Methods can be attached to an enum -impl List { - // Create an empty list - fn new() -> List { - // `Nil` has type `List` - Nil - } - - // Consume a list, and return the same list with a new element at its front - fn prepend(self, elem: u32) -> List { - // `Cons` also has type List - Cons(elem, Box::new(self)) - } - - // Return the length of the list - fn len(&self) -> u32 { - // `self` has to be matched, because the behavior of this method - // depends on the variant of `self` - // `self` has type `&List`, and `*self` has type `List`, matching on a - // concrete type `T` is preferred over a match on a reference `&T` - match *self { - // Can't take ownership of the tail, because `self` is borrowed; - // instead take a reference to the tail - Cons(_, ref tail) => 1 + tail.len(), - // Base Case: An empty list has zero length - Nil => 0 - } - } - - // Return representation of the list as a (heap allocated) string - fn stringify(&self) -> String { - match *self { - Cons(head, ref tail) => { - // `format!` is similar to `print!`, but returns a heap - // allocated string instead of printing to the console - format!("{}, {}", head, tail.stringify()) - }, - Nil => { - format!("Nil") - }, - } +// A function which takes a `Person` enum as an argument and +// returns nothing. +fn inspect(p: Person) { + // Usage of an `enum` must cover all cases (irrefutable) + // so a `match` is used to branch over it. + match p { + Person::Skinny => println!("Is skinny!"), + Person::Fat => println!("Is fat!"), + // Destructure `i` from inside the `enum`. + Person::Height(i) => println!("Has a height of {}.", i), + Person::Weight(i) => println!("Has a weight of {}.", i), + // Destructure `Info` into `name` and `height`. + Person::Info { name, height } => { + println!("{} is {} tall!", name, height); + }, } } fn main() { - // Create an empty linked list - let mut list = List::new(); - - // Append some elements - list = list.prepend(1); - list = list.prepend(2); - list = list.prepend(3); + let person = Person::Height(18); + // `to_owned()` creates an owned `String` from a string slice. + let dave = Person::Info { name: "Dave".to_owned(), height: 72 }; + // ^ TODO: Try changing these to a different variants. - // Show the final state of the list - println!("linked list has length: {}", list.len()); - println!("{}", list.stringify()); + inspect(person); + inspect(dave); } diff --git a/examples/custom_types/enum/enum_use/input.md b/examples/custom_types/enum/enum_use/input.md new file mode 100644 index 0000000000..3641651ce4 --- /dev/null +++ b/examples/custom_types/enum/enum_use/input.md @@ -0,0 +1,10 @@ +The `use` declaration can be used so manually scoping isn't needed: + +{use.play} + +### See also: + +[`match`][match] and [`use`][use] + +[use]: /mod/use.html +[match]: /flow_control/match.html diff --git a/examples/custom_types/enum/enum_use/use.rs b/examples/custom_types/enum/enum_use/use.rs new file mode 100644 index 0000000000..822a467cb1 --- /dev/null +++ b/examples/custom_types/enum/enum_use/use.rs @@ -0,0 +1,36 @@ +// An attribute to hide warnings for unused code. +#![allow(dead_code)] + +// Explicitly `use` each name so they are available without +// manual scoping. +use Status::{Poor, Rich}; + +// Automatically `use` each name inside `Work`. +use Work::*; + +enum Status { + Rich, + Poor, +} + +enum Work { + Civilian, + Soldier, +} + +fn main() { + // Equivalent to `Status::Poor`. + let status = Poor; + // Equivalent to `Work::Civilian`. + let work = Civilian; + + match status { + Rich => println!("The rich have lots of money!"), + Poor => println!("The poor have no money..."), + } + + match work { + Civilian => println!("Civilians work!"), + Soldier => println!("Soldiers fight!"), + } +} diff --git a/examples/custom_types/enum/input.md b/examples/custom_types/enum/input.md index 4b5b001b83..e4b426be2c 100644 --- a/examples/custom_types/enum/input.md +++ b/examples/custom_types/enum/input.md @@ -1,9 +1,15 @@ -The `enum` keyword allows the creation of -[tagged unions][tag-union], which can be used -as algebraic data types -([ADT][adt]). +The `enum` keyword allows the creation of a type which may be one of a few +different variants. Any variant which is valid as a `struct` is also valid as +an `enum`. {enum.play} -[adt]: http://en.wikipedia.org/wiki/Algebraic_data_type -[tag-union]: http://en.wikipedia.org/wiki/Tagged_union +### See also: + +[`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] + +[attributes]: /attribute.html +[c_struct]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[match]: /flow_control/match.html +[fn]: /fn.html +[str]: /std/str.html diff --git a/examples/custom_types/enum/testcase_linked_list/input.md b/examples/custom_types/enum/testcase_linked_list/input.md new file mode 100644 index 0000000000..c4ea99ade5 --- /dev/null +++ b/examples/custom_types/enum/testcase_linked_list/input.md @@ -0,0 +1,10 @@ +A common use for `enums` is to create a linked-list: + +{linked_list.play} + +### See also: + +[`Box`][box] and [methods][methods] + +[box]: /std/box.html +[methods]: /fn/methods.html diff --git a/examples/custom_types/enum/testcase_linked_list/linked_list.rs b/examples/custom_types/enum/testcase_linked_list/linked_list.rs new file mode 100644 index 0000000000..5a00766051 --- /dev/null +++ b/examples/custom_types/enum/testcase_linked_list/linked_list.rs @@ -0,0 +1,66 @@ +use List::*; + +enum List { + // Cons: Tuple struct that wraps an element and a pointer to the next node + Cons(u32, Box), + // Nil: A node that signifies the end of the linked list + Nil, +} + +// Methods can be attached to an enum +impl List { + // Create an empty list + fn new() -> List { + // `Nil` has type `List` + Nil + } + + // Consume a list, and return the same list with a new element at its front + fn prepend(self, elem: u32) -> List { + // `Cons` also has type List + Cons(elem, Box::new(self)) + } + + // Return the length of the list + fn len(&self) -> u32 { + // `self` has to be matched, because the behavior of this method + // depends on the variant of `self` + // `self` has type `&List`, and `*self` has type `List`, matching on a + // concrete type `T` is preferred over a match on a reference `&T` + match *self { + // Can't take ownership of the tail, because `self` is borrowed; + // instead take a reference to the tail + Cons(_, ref tail) => 1 + tail.len(), + // Base Case: An empty list has zero length + Nil => 0 + } + } + + // Return representation of the list as a (heap allocated) string + fn stringify(&self) -> String { + match *self { + Cons(head, ref tail) => { + // `format!` is similar to `print!`, but returns a heap + // allocated string instead of printing to the console + format!("{}, {}", head, tail.stringify()) + }, + Nil => { + format!("Nil") + }, + } + } +} + +fn main() { + // Create an empty linked list + let mut list = List::new(); + + // Append some elements + list = list.prepend(1); + list = list.prepend(2); + list = list.prepend(3); + + // Show the final state of the list + println!("linked list has length: {}", list.len()); + println!("{}", list.stringify()); +} diff --git a/examples/custom_types/structs/input.md b/examples/custom_types/structs/input.md index c77eae53e8..5dc15ecef6 100644 --- a/examples/custom_types/structs/input.md +++ b/examples/custom_types/structs/input.md @@ -7,4 +7,10 @@ There are three types of structures ("structs") that can be created using the {structs.play} +### See also: + +[`attributes`][attributes] and [destructuring][destructuring] + +[attributes]: /attribute.html [c_struct]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[destructuring]: /flow_control/match/destructuring.html diff --git a/examples/structure.json b/examples/structure.json index 605152a91d..cd9ddf73bf 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -17,7 +17,9 @@ { "id": "custom_types", "title": "Custom types", "children": [ { "id": "structs", "title": "Structures", "children": null }, { "id": "enum", "title": "Enums", "children": [ - { "id": "c_like", "title": "C-like", "children": null } + { "id": "enum_use", "title": "use", "children": null }, + { "id": "c_like", "title": "C-like", "children": null }, + { "id": "testcase_linked_list", "title": "Testcase: linked-list", "children": null } ] }, { "id": "constants", "title": "constants", "children": null } ] }, From 6c80d60c645ad1b9fad3c186b9fecf918d752c2b Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 26 Jun 2015 12:53:59 -0400 Subject: [PATCH 0295/1122] Move `use` into main --- examples/custom_types/enum/enum_use/use.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/custom_types/enum/enum_use/use.rs b/examples/custom_types/enum/enum_use/use.rs index 822a467cb1..63a27aa3cb 100644 --- a/examples/custom_types/enum/enum_use/use.rs +++ b/examples/custom_types/enum/enum_use/use.rs @@ -1,13 +1,6 @@ // An attribute to hide warnings for unused code. #![allow(dead_code)] -// Explicitly `use` each name so they are available without -// manual scoping. -use Status::{Poor, Rich}; - -// Automatically `use` each name inside `Work`. -use Work::*; - enum Status { Rich, Poor, @@ -19,17 +12,25 @@ enum Work { } fn main() { + // Explicitly `use` each name so they are available without + // manual scoping. + use Status::{Poor, Rich}; + // Automatically `use` each name inside `Work`. + use Work::*; + // Equivalent to `Status::Poor`. let status = Poor; // Equivalent to `Work::Civilian`. let work = Civilian; match status { + // Note the lack of scoping because of the explicit `use` above. Rich => println!("The rich have lots of money!"), Poor => println!("The poor have no money..."), } match work { + // Note again the lack of scoping. Civilian => println!("Civilians work!"), Soldier => println!("Soldiers fight!"), } From b6dffba83d11088bf3c06ac6124997a951384683 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 26 Jun 2015 13:02:21 -0400 Subject: [PATCH 0296/1122] Typo --- examples/custom_types/enum/enum_use/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_types/enum/enum_use/input.md b/examples/custom_types/enum/enum_use/input.md index 3641651ce4..86b44e6651 100644 --- a/examples/custom_types/enum/enum_use/input.md +++ b/examples/custom_types/enum/enum_use/input.md @@ -1,4 +1,4 @@ -The `use` declaration can be used so manually scoping isn't needed: +The `use` declaration can be used so manual scoping isn't needed: {use.play} From 46b1e6c93f8eaad1202bdca684b60156c892bc24 Mon Sep 17 00:00:00 2001 From: Cornel Punga Date: Tue, 30 Jun 2015 19:13:56 +0300 Subject: [PATCH 0297/1122] [Fn|Closures|OutputParameters] Update explanation I consider that it is important for the reader to know to which version of Rust Lang does refer the author. ** Version 1.1.0 was introduced, but I am not sure it is correct. If I am wrong, excuse me and please indicate the correct one. ** --- examples/fn/closures/output_parameters/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index 0144555114..c650c58099 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -9,7 +9,7 @@ The valid types for returns are slightly different than before: * `Fn`: normal * `FnMut`: normal * `FnBox`: equivalent to `FnOnce` but specialized for this application -because `FnOnce` currently interacts badly with the type system. +because `FnOnce` currently(version 1.1.0) interacts badly with the type system. Beyond this, the `move` keyword must be used which signals that all captures occur by value. This is required because any captures by reference would be From 11ac37eb0c593ce6b0408a467be178b2682aeaa8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 1 Jul 2015 01:08:22 -0400 Subject: [PATCH 0298/1122] Typo: eat to consume --- examples/fn/closures/capture/capture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/capture/capture.rs b/examples/fn/closures/capture/capture.rs index a5045d7ea2..a6cfbb6b7a 100644 --- a/examples/fn/closures/capture/capture.rs +++ b/examples/fn/closures/capture/capture.rs @@ -45,7 +45,7 @@ fn main() { drop(movable); }; - // `eat` consumes the variable so this can only be called once. + // `consume` consumes the variable so this can only be called once. consume(); //consume(); // ^ TODO: Try uncommenting this line. From 2eead728bfeae7261cc00a36f2ce781adfe69d64 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 14 Jun 2015 17:29:09 -0300 Subject: [PATCH 0299/1122] This overlap is currently allowed --- examples/generics/impl/input.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 9ad3b2bfc4..fd0f6ffde1 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -12,10 +12,6 @@ impl GenericVal {} // Specialize to `S` defined above impl GenericVal {} ``` -Note: Rust does not *currently* allow overlap between implementations. The -3 separate implementations of `GenericVal` above cannot coexist. There are -[plans][specialization_plans] to fix this though. - {impl.play} ### See also: From f3f218cc4c5895d89c65448e58e14d61de24b163 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 2 Jul 2015 13:34:05 -0300 Subject: [PATCH 0300/1122] Explain HOFs in terms of functions instead of closures --- examples/fn/hof/input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fn/hof/input.md b/examples/fn/hof/input.md index 20215b05d8..0ee321be7c 100644 --- a/examples/fn/hof/input.md +++ b/examples/fn/hof/input.md @@ -1,6 +1,6 @@ -Rust provides Higher Order Functions (HOF). These are functions that take a -closure as an argument to produce a more useful function. HOFs and lazy -iterators give Rust its functional flavor. +Rust provides Higher Order Functions (HOF). These are functions that +take one or more functions and/or produce a more useful function. HOFs +and lazy iterators give Rust its functional flavor. {hof.play} From 869d4d1a165e51cd5aac81dcc9f51b916f57d980 Mon Sep 17 00:00:00 2001 From: RTR Date: Fri, 3 Jul 2015 18:45:24 +0530 Subject: [PATCH 0301/1122] Added tuple destruct Tuple destructuring is very useful. Is it discussed somewhere else? If so, why not here? --- examples/primitives/tuples/tuples.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/primitives/tuples/tuples.rs b/examples/primitives/tuples/tuples.rs index 646dfcec75..d6f8d8742f 100644 --- a/examples/primitives/tuples/tuples.rs +++ b/examples/primitives/tuples/tuples.rs @@ -32,4 +32,10 @@ fn main() { // from a literal surrounded by parentheses println!("one element tuple: {:?}", (5u32,)); println!("just an integer: {:?}", (5u32)); + + //tuples can be destructured to create bindings + let tuple = (1, "hello", 4.5, true); + + let (a, b, c, d) = tuple; + println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d); } From 235297d980290a0ad0af4809eaa1d0dac202dd24 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Mon, 6 Jul 2015 00:16:17 -0700 Subject: [PATCH 0302/1122] Correct explanation of where clauses Where clauses don't apply bounds to arbitrary expressions, they apply bounds to arbitrary types (`Option`). The other form is limited in that it can only apply bounds to a type parameter (`T`). --- examples/generics/where/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/where/input.md b/examples/generics/where/input.md index ba1774de3a..3aaabe24ea 100644 --- a/examples/generics/where/input.md +++ b/examples/generics/where/input.md @@ -13,7 +13,7 @@ impl MyTrait for YourType where ``` * `where` clauses are more expressive than the normal syntax. They can -apply bounds to arbitrary expressions rather than just types. The +apply bounds to arbitrary types rather than just type parameters. The following example cannot be directly expressed without a `where` clause: {where.play} From 1d81ce07cbf92f0ef6dfbf6366b0029669bb6f2f Mon Sep 17 00:00:00 2001 From: machty Date: Mon, 6 Jul 2015 10:11:36 -0400 Subject: [PATCH 0303/1122] fn/closures: fix typo --- examples/fn/closures/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 3ddbe60652..9186f9bb3c 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -1,5 +1,5 @@ Closures[^*] in Rust are functions with a slightly specialized syntax which -can capture the enclosing environment. Their syntax and capabilties make them +can capture the enclosing environment. Their syntax and capabilities make them very convenient for on the fly usage. Some characteristics include: * uses `||` instead of `()` around input variables. From 767b7f7490b0d75aa5700854340e289ee79c1a49 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Jul 2015 14:40:44 -0400 Subject: [PATCH 0304/1122] Update cargo lock --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 849b7d4c44..68946aaf1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,48 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.30" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" From b6d46e97e199f35cb301c37473356b7e5ee3dc5e Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Jul 2015 22:36:10 -0400 Subject: [PATCH 0305/1122] Notify me of build failures --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 185a056f94..0330db292e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,10 @@ script: - make test - make book +notifications: + email: + - mdinger.bugzilla@gmail.com + after_success: - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh From cc7aa15b717851b322154bd351a49ffc95d9b99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20=C4=BDach?= Date: Mon, 13 Jul 2015 20:31:43 +0100 Subject: [PATCH 0306/1122] lifetimes/structs expand unclear abbreviation --- examples/scope/lifetime/struct/struct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/struct/struct.rs b/examples/scope/lifetime/struct/struct.rs index 9b8f1fb4dc..83108ba99b 100644 --- a/examples/scope/lifetime/struct/struct.rs +++ b/examples/scope/lifetime/struct/struct.rs @@ -12,7 +12,7 @@ struct Pair<'a, 'b> { } fn main() { - // Let's say that `one` has lifetime `o` + // Let us say that `one` has lifetime `o` let mut one = 1; { From af64ffd0c6146ddcd9a1fdc5b9f156ed918716b8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 23 Jul 2015 12:49:38 -0400 Subject: [PATCH 0307/1122] Use local highlighting file until ace-builds updates again --- node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak | 1 + setup-stage.sh | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak diff --git a/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak b/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak new file mode 100644 index 0000000000..01562cc9ae --- /dev/null +++ b/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak @@ -0,0 +1 @@ +ace.define("ace/mode/rust_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=/\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\})/.source,o=function(){this.$rules={start:[{token:"variable.other.source.rust",regex:"'[a-zA-Z_][a-zA-Z0-9_]*(?![\\\'])"},{token:"string.quoted.single.source.rust",regex:"'(?:[^'\\\\]|"+s+")'"},{stateName:"bracketedComment",onMatch:function(e,t,n){return n.unshift(this.next,e.length-1,t),"string.quoted.raw.source.rust"},regex:/r#*"/,next:[{onMatch:function(e,t,n){var r="string.quoted.raw.source.rust";return e.length>=n[1]?(e.length>n[1]&&(r="invalid"),n.shift(),n.shift(),this.next=n.shift()):this.next="",r},regex:/"#*/,next:"start"},{defaultToken:"string.quoted.raw.source.rust"}]},{token:"string.quoted.double.source.rust",regex:'"',push:[{token:"string.quoted.double.source.rust",regex:'"',next:"pop"},{token:"constant.character.escape.source.rust",regex:s},{defaultToken:"string.quoted.double.source.rust"}]},{token:["keyword.source.rust","text","entity.name.function.source.rust"],regex:"\\b(fn)(\\s+)([a-zA-Z_][a-zA-Z0-9_]*)"},{token:"support.constant",regex:"\\b[a-zA-Z_][\\w\\d]*::"},{token:"keyword.source.rust",regex:"\\b(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\\b"},{token:"storage.type.source.rust",regex:"\\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b"},{token:"variable.language.source.rust",regex:"\\bself\\b"},{token:"keyword.operator",regex:/\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/},{token:"punctuation.operator",regex:/[?:,;.]/},{token:"paren.lparen",regex:/[\[({]/},{token:"paren.rparen",regex:/[\])}]/},{token:"constant.language.source.rust",regex:"\\b(?:true|false|Some|None|Ok|Err)\\b"},{token:"support.constant.source.rust",regex:"\\b(?:EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\\b"},{token:"meta.preprocessor.source.rust",regex:"\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b"},{token:"constant.numeric.integer.source.rust",regex:"\\b(?:[0-9][0-9_]*|[0-9][0-9_]*(?:u|us|u8|u16|u32|u64)|[0-9][0-9_]*(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.hex.source.rust",regex:"\\b(?:0x[a-fA-F0-9_]+|0x[a-fA-F0-9_]+(?:u|us|u8|u16|u32|u64)|0x[a-fA-F0-9_]+(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.binary.source.rust",regex:"\\b(?:0b[01_]+|0b[01_]+(?:u|us|u8|u16|u32|u64)|0b[01_]+(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.float.source.rust",regex:"[0-9][0-9_]*(?:f32|f64|f)|[0-9][0-9_]*[eE][+-]=[0-9_]+|[0-9][0-9_]*[eE][+-]=[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+|[0-9][0-9_]*\\.[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+(?:f32|f64|f)"},{token:"comment.line.documentation.source.rust",regex:"//!.*$",push_:[{token:"comment.line.documentation.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.documentation.source.rust"}]},{token:"comment.line.double-dash.source.rust",regex:"//.*$",push_:[{token:"comment.line.double-dash.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.source.rust"}]},{token:"comment.start.block.source.rust",regex:"/\\*",stateName:"comment",push:[{token:"comment.start.block.source.rust",regex:"/\\*",push:"comment"},{token:"comment.end.block.source.rust",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.source.rust"}]}]},this.normalizeRules()};o.metaData={fileTypes:["rs","rc"],foldingStartMarker:"^.*\\bfn\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$",foldingStopMarker:"^\\s*\\}",name:"Rust",scopeName:"source.rust"},r.inherits(o,i),t.RustHighlightRules=o}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/rust",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/rust_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./rust_highlight_rules").RustHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/rust"}.call(u.prototype),t.Mode=u}) diff --git a/setup-stage.sh b/setup-stage.sh index eca4b5fed2..f45626264f 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -6,7 +6,8 @@ ace_playpen_local='node_modules/gitbook-plugin-rust-playpen' mkdir -p bin mkdir -p stage/node_modules svn checkout ${ace_repository} ${ace_playpen_local}'/book/ace' -cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' +# cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' +cp ${ace_playpen_local}'/book/mode-rust.js.bak' ${ace_playpen_local}'/book/mode-rust.js' ln -sf ../book.json stage ln -sf ../examples/README.md stage From 7f976f6c3fe226d27f140946867ab6fd32d4ec11 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 25 Jul 2015 14:36:13 -0400 Subject: [PATCH 0308/1122] Fix some warnings --- examples/std_misc/arg/args.rs | 4 +--- examples/std_misc/arg/getopts/echo.rs | 5 ++--- examples/std_misc/arg/getopts/testopt.rs | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/std_misc/arg/args.rs b/examples/std_misc/arg/args.rs index 0d399076d4..f440abe2ed 100644 --- a/examples/std_misc/arg/args.rs +++ b/examples/std_misc/arg/args.rs @@ -1,5 +1,3 @@ -#![feature(slice_extras)] - use std::env; fn main() { @@ -11,5 +9,5 @@ fn main() { // The rest of the arguments are the passed command line parameters. // Call the program like this: // $ ./args arg1 arg2 - println!("I got {:?} arguments: {:?}.", args.len() - 1, args.tail()); + println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]); } diff --git a/examples/std_misc/arg/getopts/echo.rs b/examples/std_misc/arg/getopts/echo.rs index c115f4b1a1..0316b85c2d 100644 --- a/examples/std_misc/arg/getopts/echo.rs +++ b/examples/std_misc/arg/getopts/echo.rs @@ -1,5 +1,4 @@ #![feature(rustc_private)] -#![feature(slice_extras)] extern crate getopts; @@ -25,7 +24,7 @@ fn main() { "output version information and exit"), ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => { println!("{}", f); @@ -56,7 +55,7 @@ fn main() { if !matches.free.is_empty() { //^ `matches.free` contains all the arguments that are not options. - let string = matches.free.connect(" "); + let string = matches.free.join(" "); println!("{}", string); } diff --git a/examples/std_misc/arg/getopts/testopt.rs b/examples/std_misc/arg/getopts/testopt.rs index cfe7c0a431..25302bbea8 100644 --- a/examples/std_misc/arg/getopts/testopt.rs +++ b/examples/std_misc/arg/getopts/testopt.rs @@ -1,5 +1,4 @@ #![feature(rustc_private)] -#![feature(slice_extras)] extern crate getopts; @@ -18,7 +17,7 @@ fn main() { // Use `optmulti`, `optflagmulti` if options can occur multiple times. ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => { println!("{}", f); From 2b2b9efc5bd8b3af1bfcc5c78b1f66269ab1c03d Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Thu, 30 Jul 2015 13:41:35 -0400 Subject: [PATCH 0309/1122] Fix typo in comment on Iterator::find The comment appears to have been copy-and-pasted from the `Iterator::any` example on the previous page, and the comment still had `\`and\`` instead of `\`find\`` in its description of the method. --- examples/fn/closures/closure_analysis/iter_find/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/closure_analysis/iter_find/input.md b/examples/fn/closures/closure_analysis/iter_find/input.md index 895f439b9d..b965742ca5 100644 --- a/examples/fn/closures/closure_analysis/iter_find/input.md +++ b/examples/fn/closures/closure_analysis/iter_find/input.md @@ -7,7 +7,7 @@ pub trait Iterator { // The type being iterated over. type Item; - // `any` takes `&mut self` meaning the caller may be borrowed + // `find` takes `&mut self` meaning the caller may be borrowed // and modified, but not consumed. fn find

", escape(source)) } From a45c982840adbc4151e011d12bd44c699083c013 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 13 Apr 2016 13:02:05 -0700 Subject: [PATCH 0442/1122] Updated 16.1 Fix some syntax errors and remove redundancy --- examples/error/unwrap/input.md | 30 ++++++++++++++---------------- examples/error/unwrap/unwrap.rs | 15 +++++++-------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/examples/error/unwrap/input.md b/examples/error/unwrap/input.md index 921a8b6616..119aaf1215 100644 --- a/examples/error/unwrap/input.md +++ b/examples/error/unwrap/input.md @@ -1,23 +1,21 @@ -We determined a snake is an inappropriate gift for a princess. What if she expected a gift -but did not receive one? Clearly that would be just as bad but how would it be handled? Well, -`Option` is the type which is used when absense is a possibility. This manifests itself as -two choices: +We determined a snake is an inappropriate gift for a princess. But what if +she expected a gift and didn't receive one? That would be just as bad, so +it needs to be handled! In the `std` library, an `enum` called `Option` +is used when absence is a possibility. It manifests itself as one of +two "options": -* `Some`: An element `T` was found +* `Some(T)`: An element of type `T` was found * `None`: No element was found -These can either be explicitly handled via `match` or implicitly with `unwrap`. `unwrap`, -deferring to the std library, either returns the inner element or `panics`. Regardless of -explicit or implicit handling, an `enum` such as `Option` will have all cases handled. The -compiler ensures that none are forgotten giving us more confidence in its robustness. +These can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling either returns the inner element or `panic`s. -{unwrap.play} - -As you can see, direct control yielded an even nicer result than the original `panic` along -with the choice to `panic` if we desired. `unwrap` on the other hand, deferring to the std -library left us with the most generic and unhelpful: "I unwrapped a `None`!" meanwhile yielding -the good results the rest of the time. A more meaningful message will require a better approach[^1]. +Note that it's possible to manually customize `panic` with +[expect][expect], but `unwrap` otherwise leaves us with a less +meaningful output than explicit handling. In the following example, +explicit handling yields a more controlled result while retaining the +option to `panic` if desired. -[^1]: ignoring [expect][expect] which allows manual customization of the `panic` for now +{unwrap.play} [expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/unwrap/unwrap.rs b/examples/error/unwrap/unwrap.rs index d0d772ae7b..898728cd46 100644 --- a/examples/error/unwrap/unwrap.rs +++ b/examples/error/unwrap/unwrap.rs @@ -1,18 +1,17 @@ -// The commoner cannot bring down the task which precludes the option of `panic`. -// These must all be handled manually. `match` would be the correct approach. +// The commoner has seen it all, and handles situations well. +// All gifts are handled manually using `match`. fn give_commoner(gift: Option<&str>) { - // Specify a specific course of action for each case. + // Specify a course of action for each case. match gift { - Some("snake") => println!("Yuck! Throws the snake in the fire."), - Some(inner) => println!("{}! How nice.", inner), + Some("snake") => println!("Yuck! I'm throwing that snake in a fire."), + Some(inner) => println!("{}? How nice.", inner), None => println!("No gift? Oh well."), } } -// A princess is allowed to bring down the task at will so `panic` is an option. +// Our sheltered princess will `panic` at the sight of snakes. fn give_princess(gift: Option<&str>) { - // Using `unwrap` defers the case analysis to the std library which will - // `panic` when it receives a `None`. + // Using `unwrap` returns a `panic` when it receives a `None`. let inside = gift.unwrap(); if inside == "snake" { panic!("AAAaaaaa!!!!"); } From 4f19d317314840ff899581126cc0bcc9c6498416 Mon Sep 17 00:00:00 2001 From: Tomasz Pasternak Date: Wed, 13 Apr 2016 22:16:48 +0200 Subject: [PATCH 0443/1122] Installation of calibre added to travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 0ba6bb790b..7bb2e271ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ install: - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz - tar xf node.tar.gz - export PATH=$PATH:$pwd/node-v0.12.7-linux-x64/bin + - apt-get install -y calibre script: - rustc --version From bc89df153f86a8476e98583cf88f0ca385976a7a Mon Sep 17 00:00:00 2001 From: Tomasz Pasternak Date: Wed, 13 Apr 2016 22:19:48 +0200 Subject: [PATCH 0444/1122] Added "sudo" to installation cmd in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7bb2e271ab..01c004ff35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ install: - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz - tar xf node.tar.gz - export PATH=$PATH:$pwd/node-v0.12.7-linux-x64/bin - - apt-get install -y calibre + - sudo apt-get install -y calibre script: - rustc --version From 91d9b1f695f4a07890df41954cccbae924c41eb1 Mon Sep 17 00:00:00 2001 From: Tomasz Pasternak Date: Wed, 13 Apr 2016 22:22:45 +0200 Subject: [PATCH 0445/1122] EPUB and PDF removed from travis build --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01c004ff35..f79717928b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,15 +14,12 @@ install: - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz - tar xf node.tar.gz - export PATH=$PATH:$pwd/node-v0.12.7-linux-x64/bin - - sudo apt-get install -y calibre script: - rustc --version - make - make test - make html - - make pdf - - make epub notifications: email: From db13f4817e1a40ba0abdbfa40303c9810dc0baeb Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 13 Apr 2016 13:53:05 -0700 Subject: [PATCH 0446/1122] Updated 16.2 Remove redundancy, added more clarity to sample code and input.md --- examples/error/map/input.md | 24 ++++++++++-------------- examples/error/map/map.rs | 10 +++++----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/examples/error/map/input.md b/examples/error/map/input.md index e6018867e3..7f5fbdc7e5 100644 --- a/examples/error/map/input.md +++ b/examples/error/map/input.md @@ -1,22 +1,18 @@ -Like before, `match` is a valid method for handling an `Option` however you may find that this -gets tedious with heavy usage of `Options`. Luckily, there is an easier way. +`match` is a valid method for handling `Option`s. However, you may eventually +find heavy usage tedious; this is the case especially with operations that +are only valid with an input. -Consider the example below and in particular `peel()` and `chop()`; since each of these -operations is only valid when the input exists, it seems sensible that bad input simply means -the result is bad. This results in the simplistic mapping `Some -> Some` and `None -> None`. -This is actually so common that there is a built in method for it called `map()` which is -already implemented on `Option`. +For situations where a simplistic mapping of `Some -> Some` and +`None -> None` is needed, `Option` has a built in method called `map()`. -The result of this is that `chop()` is simpler to write than any of the previous methods. -Furthermore, the ability to chain these together makes it even more flexible; `process()` -easily can replace all the previous functions and still be compact. +Multiple `map()` calls can be chained together for even more flexibility. +In the following example, `process()` easily replaces all functions previous +to it while staying compact. {map.play} -[option]: http://doc.rust-lang.org/std/option/enum.Option.html - ### See also: -[`struct`s][structs] +[closures][closures] -[structs]: /custom_types/structs.html +[closures]: /fn/closures.html diff --git a/examples/error/map/map.rs b/examples/error/map/map.rs index 1db9ee57ff..9c09d72e77 100644 --- a/examples/error/map/map.rs +++ b/examples/error/map/map.rs @@ -15,8 +15,7 @@ fn peel(food: Option) -> Option { } } -// Similarly, we still need to keep track of whether there is a problem. If there -// is, we just pass it on. +// Like above, we need to know if the peeled food exists before chopping. fn chop(peeled: Option) -> Option { match peeled { Some(Peeled(food)) => Some(Chopped(food)), @@ -24,19 +23,20 @@ fn chop(peeled: Option) -> Option { } } -// Same as before, when `Some`, pass `food` to `Cooked`, otherwise return `None`. +// Similar to previous checks, but using `map()` instead of `match`. fn cook(chopped: Option) -> Option { chopped.map(|Chopped(food)| Cooked(food)) } -// You could even simplify the process further +// Alternatively, we can chain multiple uses of `map()` to simplify +// the above process. fn process(food: Option) -> Option { food.map(|f| Peeled(f)) .map(|Peeled(f)| Chopped(f)) .map(|Chopped(f)| Cooked(f)) } -// Can we eat it now? +// It's important to know whether there's food or not before trying to eat it! fn eat(food: Option) { match food { Some(food) => println!("Mmm. I love {:?}", food), From 446b398d12db62906a100971d594c5fc5791dd7b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 13 Apr 2016 16:11:04 -0700 Subject: [PATCH 0447/1122] Rename Ch16.3, remove redundancies and improve readability Renamed more_combinators to and_then based on content; changed some wordings for clarity and removed some confusing information of questionable use to first time readers --- .../combinators.rs => and_then/and_then.rs} | 11 ++++--- examples/error/and_then/input.md | 20 +++++++++++++ examples/error/input.md | 5 ++-- examples/error/more_combinators/input.md | 30 ------------------- examples/structure.json | 2 +- 5 files changed, 29 insertions(+), 39 deletions(-) rename examples/error/{more_combinators/combinators.rs => and_then/and_then.rs} (75%) create mode 100644 examples/error/and_then/input.md delete mode 100644 examples/error/more_combinators/input.md diff --git a/examples/error/more_combinators/combinators.rs b/examples/error/and_then/and_then.rs similarity index 75% rename from examples/error/more_combinators/combinators.rs rename to examples/error/and_then/and_then.rs index 056ec343f0..2f18a20ff7 100644 --- a/examples/error/more_combinators/combinators.rs +++ b/examples/error/and_then/and_then.rs @@ -11,17 +11,16 @@ fn have_ingredients(food: Food) -> Option { } } -// We know how to make everything except Cordon Bleu. -fn can_cook(food: Food) -> Option { +// We have the recipe for everything except Cordon Bleu. +fn have_recipe(food: Food) -> Option { match food { Food::CordonBleu => None, _ => Some(food), } } -// To make a meal, we require both the ingredients and the ability to make that -// meal, which is only possible when both are true; thus successes chain. -// Conveniently, this can be rewritten more compactly with `and_then()`. +// To make a dish, we need both the ingredients and the recipe. +// We can represent the logic with a chain of `match`es: fn cookable_v1(food: Food) -> Option { match have_ingredients(food) { None => None, @@ -32,7 +31,7 @@ fn cookable_v1(food: Food) -> Option { } } -// Same as `v1` above but uses `and_then()` instead. +// This can conveniently be rewritten more compactly with `and_then()`: fn cookable_v2(food: Food) -> Option { have_ingredients(food).and_then(can_cook) } diff --git a/examples/error/and_then/input.md b/examples/error/and_then/input.md new file mode 100644 index 0000000000..3eca809378 --- /dev/null +++ b/examples/error/and_then/input.md @@ -0,0 +1,20 @@ +`map()` was described as a chainable way to simplify `match` statements. +However, using `map()` on a function that returns an `Option` results +in the nested `Option>`. Chaining multiple calls together can +then become confusing. + +That's where `and_then()` comes in. Known in some languages as flatmap, `and_then()` calls its function input with the wrapped value or returns `None` if the `Option` is `None`. + +In the following example, `cookable_v2()` results in an `Option`. +Using `map()` instead of `and_then()` would have given an `Option>`, +which is an invalid type for `eat()`. + +{combinators.play} + +### See also: + +[`Option`][option], [`Option::map()`][map], and [`Option::and_then()`][and_then] + +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map +[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/input.md b/examples/error/input.md index fdbd1a9735..6ea85cad1c 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -17,5 +17,6 @@ with the snake, but this is not reliable. The problem is that programmers do not habitually test these checks unless required to by the compiler. In order for this to be reliable, we'll want the compiler to point out -cases where there may not be a gift. As you'll see in the next section, we -can use `Option` to take care of this condition. +cases where there may not be a gift. In this chapter, we will learn to use +`Option` to take care of this condition, as well as various functions to +deal with the results of one or more uses of `Option`. diff --git a/examples/error/more_combinators/input.md b/examples/error/more_combinators/input.md deleted file mode 100644 index 2c733af5d5..0000000000 --- a/examples/error/more_combinators/input.md +++ /dev/null @@ -1,30 +0,0 @@ -`map()` was previously described as a way to simplify a `match` which also allows chaining. -However, `map()` does not work for all cases because the constituents often occur in many -different combinations. Consider the following example: - -{combinators.play} - -The reason this worked is because `and_then()` happened to require the exact function type as an -input that was needed here. `map()` did not. Comparing the signatures of their input types, you -will see that when the function returned an `Option`, `and_then()` became the one and *only* -valid choice. - -```rust -map(): FnOnce(T) -> U -and_then(): FnOnce(T) -> Option -``` - -These are just two of many different combinators that are implemented on -[`Option`][option] by the std library for many different use cases. It is advantageous -to become familiar with them because they can simplify many error handling procedures and -avoid the ugly and suicidal `panic!()` alternative. The other common error handling type, -`Result`, also uses most of these same constructs so the skills are transferable. - - -### See also: - -[`Option`][option], [`Option::map()`][map], and [`Option::and_then()`][and_then] - -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map -[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/structure.json b/examples/structure.json index baf91938e4..cb688764f1 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -142,7 +142,7 @@ { "id": "error", "title": "Error handling", "children": [ { "id": "unwrap", "title": "Option & unwrap", "children": null }, { "id": "map", "title": "map", "children": null }, - { "id": "more_combinators", "title": "More combinators", "children": null }, + { "id": "and_then", "title": "and_then", "children": null }, { "id": "error_vs_absence", "title": "Errors vs Absence", "children": null }, { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "Result as an alias", "children": null }, From 561e125d527ecb2de109d5cfbb64f8efc24fd2a3 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 13 Apr 2016 16:19:35 -0700 Subject: [PATCH 0448/1122] Rename Ch16.4 to Result Rename section to better reflect content --- examples/error/{error_vs_absence => result}/input.md | 0 examples/error/{error_vs_absence => result}/result.rs | 0 examples/structure.json | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename examples/error/{error_vs_absence => result}/input.md (100%) rename examples/error/{error_vs_absence => result}/result.rs (100%) diff --git a/examples/error/error_vs_absence/input.md b/examples/error/result/input.md similarity index 100% rename from examples/error/error_vs_absence/input.md rename to examples/error/result/input.md diff --git a/examples/error/error_vs_absence/result.rs b/examples/error/result/result.rs similarity index 100% rename from examples/error/error_vs_absence/result.rs rename to examples/error/result/result.rs diff --git a/examples/structure.json b/examples/structure.json index cb688764f1..6364343951 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -143,7 +143,7 @@ { "id": "unwrap", "title": "Option & unwrap", "children": null }, { "id": "map", "title": "map", "children": null }, { "id": "and_then", "title": "and_then", "children": null }, - { "id": "error_vs_absence", "title": "Errors vs Absence", "children": null }, + { "id": "result", "title": "Result", "children": null }, { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "Result as an alias", "children": null }, { "id": "option_with_result", "title": "Options with Results", "children": [ From 5343fd48a9cf67f83643acd580fdb80e81dd04d1 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 13 Apr 2016 20:03:04 -0400 Subject: [PATCH 0449/1122] Cargo update --- Cargo.lock | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2132fd5020..e4ae36464f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,8 +2,8 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.65 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -11,41 +11,47 @@ name = "aho-corasick" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.2.7" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mempool" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "regex" -version = "0.1.55" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mempool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] From bd6e5f92019e3f02a8507410e72df534ce41582a Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 14 Apr 2016 14:38:57 -0700 Subject: [PATCH 0450/1122] Changed .play to match renaming --- examples/error/and_then/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error/and_then/input.md b/examples/error/and_then/input.md index 3eca809378..f28d828394 100644 --- a/examples/error/and_then/input.md +++ b/examples/error/and_then/input.md @@ -9,7 +9,7 @@ In the following example, `cookable_v2()` results in an `Option`. Using `map()` instead of `and_then()` would have given an `Option>`, which is an invalid type for `eat()`. -{combinators.play} +{and_then.play} ### See also: From 523c09a5a508e6e04b4b5fa4dcd86ac52fdcfa2b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 18 Apr 2016 13:18:24 -0700 Subject: [PATCH 0451/1122] Fix for unresolved name can_cook -> have_ingredients --- examples/error/and_then/and_then.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/error/and_then/and_then.rs b/examples/error/and_then/and_then.rs index 2f18a20ff7..35dcda831c 100644 --- a/examples/error/and_then/and_then.rs +++ b/examples/error/and_then/and_then.rs @@ -24,7 +24,7 @@ fn have_recipe(food: Food) -> Option { fn cookable_v1(food: Food) -> Option { match have_ingredients(food) { None => None, - Some(food) => match can_cook(food) { + Some(food) => match have_recipe(food) { None => None, Some(food) => Some(food), }, @@ -33,7 +33,7 @@ fn cookable_v1(food: Food) -> Option { // This can conveniently be rewritten more compactly with `and_then()`: fn cookable_v2(food: Food) -> Option { - have_ingredients(food).and_then(can_cook) + have_ingredients(food).and_then(have_recipe) } fn eat(food: Food, day: Day) { From 6feee678dd1528a0260a4ba4708a2e2c17aff083 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 18 Apr 2016 13:47:59 -0700 Subject: [PATCH 0452/1122] Fix for alternate names --- examples/fn/closures/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 45a64f077b..0242b3cc08 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -1,4 +1,4 @@ -Closures in Rust, also called lambdas or anonymous functions, are functions +Closures in Rust, also called lambdas, are functions that can capture the enclosing environment. Their syntax and capabilities make them very convenient for on the fly usage. Some characteristics include: From af9344073fb1c21d3bf0a85165dfc61fca8d1dc5 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 26 Apr 2016 19:12:15 -0700 Subject: [PATCH 0453/1122] Updated Ch13 Generics Clarify language and fix punctuation --- examples/generics/generics.rs | 2 +- examples/generics/input.md | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index 14fd2cb6c2..6386f82246 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -16,7 +16,7 @@ fn main() { let _s = Single(A); // Create a variable `_char` of type `SingleGen` - // and give it the value `SingleGen('a')` + // and give it the value `SingleGen('a')`. // Here, `SingleGen` has a type parameter explicitly specified. let _char: SingleGen = SingleGen('a'); diff --git a/examples/generics/input.md b/examples/generics/input.md index 15ac2795ae..f6f10cee6b 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -1,11 +1,12 @@ -Generics is the topic of generalizing types and functionality to broader -cases. This is extremely useful in reducing code duplication in many ways, -but requires a rather involving syntax. However, we will find that being -generic involves taking great care to specify over what types a generic type -is actually considered valid. - -A type parameter is specified as generic by the use of angle brackets and -[camel case][camelcase]: ``. "Generic type parameters" are +*Generics* is the topic of generalizing types and functionalities to broader +cases. This is extremely useful for reducing code duplication in many ways, +but can call for rather involving syntax. Namely, being generic requires +taking great care to specify over which types a generic type +is actually considered valid. The simplest and most common use of generics +is for type parameters. + +A type parameter is specified as generic by the use of angle brackets and upper +[camel case][camelcase]: ``. "Generic type parameters" are typically represented as ``. In Rust, "generic" also describes anything that accepts one or more generic type parameters ``. Any type specified as a generic type parameter is generic, and everything else is concrete (non-generic). @@ -17,9 +18,9 @@ For example, defining a *generic function* named `foo` that takes an argument fn foo(T) { ... } ``` -Because `T` has been specified as a generic type parameter, it is considered -generic when used here as `(T)`. This is the case even if `T` has previously -been defined as a `struct`. +Because `T` has been specified as a generic type parameter using ``, it +is considered generic when used here as `(T)`. This is the case even if `T` +has previously been defined as a `struct`. This example shows some of the syntax in action: From 10c6476bb0e4915c9397a38f5d22a0058e544002 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 26 Apr 2016 19:12:51 -0700 Subject: [PATCH 0454/1122] Updated Ch13.1 Fix punctuation and minor grammar changes --- examples/generics/gen_fn/fn.rs | 20 ++++++++++---------- examples/generics/gen_fn/input.md | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs index 01e32d8bec..04bcb31bce 100644 --- a/examples/generics/gen_fn/fn.rs +++ b/examples/generics/gen_fn/fn.rs @@ -2,24 +2,24 @@ struct A; // Concrete type `A`. struct S(A); // Concrete type `S`. struct SGen(T); // Generic type `SGen`. -// These functions all take ownership of the variable passed into -// them and immediately go out of scope freeing the variable. +// The following functions all take ownership of the variable passed into +// them and immediately go out of scope, freeing the variable. -// Define a function `reg_fn` that takes an argument `s` of type `S`. +// Define a function `reg_fn` that takes an argument `_s` of type `S`. // This has no `` so this is not a generic function. fn reg_fn(_s: S) {} -// Define a function `gen_spec_t` that takes an argument `s` of type `SGen` -// that has been explicitly given the type parameter `A`. Because A has not -// been specified as a generic type parameter for gen_spec_t, it is not generic. +// Define a function `gen_spec_t` that takes an argument `_s` of type `SGen`. +// It has been explicitly given the type parameter `A`, but because `A` has not +// been specified as a generic type parameter for `gen_spec_t`, it is not generic. fn gen_spec_t(_s: SGen) {} -// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen` -// that has been explicitly given the type parameter `i32`. -// This function is also not generic. +// Define a function `gen_spec_i32` that takes an argument `_s` of type `SGen`. +// It has been explicitly given the type parameter `i32`, which is a specific type. +// Because `i32` is not a generic type, this function is also not generic. fn gen_spec_i32(_s: SGen) {} -// Define a function `generic` that takes an argument `s` of type `SGen`. +// Define a function `generic` that takes an argument `_s` of type `SGen`. // Because `SGen` is preceded by ``, this function is generic over `T`. fn generic(_s: SGen) {} diff --git a/examples/generics/gen_fn/input.md b/examples/generics/gen_fn/input.md index c6d37aeb97..bb4a478d49 100644 --- a/examples/generics/gen_fn/input.md +++ b/examples/generics/gen_fn/input.md @@ -1,8 +1,8 @@ The same set of rules can be applied to functions: a type `T` becomes -generic when preceded by ``. +generic when preceded by ``. Using generic functions sometimes requires explicitly specifying type -parameters. This may be if the function is called where the return type +parameters. This may be the case if the function is called where the return type is generic, or if the compiler doesn't have enough information to infer the necessary type parameters. From 5f6d42cb2e0af85308c177fc78957e150aeb45dc Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 26 Apr 2016 19:13:12 -0700 Subject: [PATCH 0455/1122] Updated Ch13.8 Fix punctuation and minor grammar changes --- examples/generics/phantom/input.md | 4 ++-- examples/generics/phantom/phantom.rs | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 76d49414e3..ad65e2eee3 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -2,8 +2,8 @@ A phantom type parameter is one that doesn't show up at runtime, but is checked statically (and only) at compile time. Data types can use extra generic type parameters to act as markers -or to perform compile-time type checking. These extra parameters -hold no storage values, and have no run-time behavior. +or to perform type checking at compile time. These extra parameters +hold no storage values, and have no runtime behavior. In the following example, we combine [std::marker::PhantomData] with the phantom type parameter concept to create tuples containing diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs index f7dd716caa..16217c0135 100644 --- a/examples/generics/phantom/phantom.rs +++ b/examples/generics/phantom/phantom.rs @@ -1,29 +1,29 @@ use std::marker::PhantomData; -// A phantom tuple struct which is generic over A with hidden parameter B. -#[derive(PartialEq)] // Allow equality test for this type +// A phantom tuple struct which is generic over `A` with hidden parameter `B`. +#[derive(PartialEq)] // Allow equality test for this type. struct PhantomTuple(A,PhantomData); -// A phantom type struct which is generic over A with hidden parameter B. -#[derive(PartialEq)] // Allow equality test for this type +// A phantom type struct which is generic over `A` with hidden parameter `B`. +#[derive(PartialEq)] // Allow equality test for this type. struct PhantomStruct { first: A, phantom: PhantomData } -// Note: Storage is allocated for generic type A, but not for B. -// Therefore, B cannot be used in computations. +// Note: Storage is allocated for generic type `A`, but not for `B`. +// Therefore, `B` cannot be used in computations. fn main() { - // Here, `f32` and `f64` - // PhantomTuple type specified as + // Here, `f32` and `f64` are the hidden parameters. + // PhantomTuple type specified as ``. let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); - // PhantomTuple type specified as + // PhantomTuple type specified as ``. let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); - // Type specified as + // Type specified as ``. let _struct1: PhantomStruct = PhantomStruct { first: 'Q', phantom: PhantomData, }; - // Type specified as + // Type specified as ``. let _struct2: PhantomStruct = PhantomStruct { first: 'Q', phantom: PhantomData, From e9fa69b54fcc1f36588743da6b6dced7fadbb9e1 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 26 Apr 2016 19:23:12 -0700 Subject: [PATCH 0456/1122] Updated Ch16.4 Minor grammar and punctuation fixes --- examples/error/result/input.md | 13 ++++++------- examples/error/result/result.rs | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/error/result/input.md b/examples/error/result/input.md index 8463926e7d..b9e03940b9 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -1,8 +1,7 @@ -Previously, we have used the type `Option` to annotate that absence is a possibility. This -absence sometimes appears as an error, for example when `None` is unwrapped. In the more -general case where there may be multiple failure points for a multitude of different reasons, -an `Option` can be replaced by the more general `Result` type. A `Result` has these -variants: +Previously, we have used the `Option` type to annotate that absence is a possibility. This +absence sometimes appears as an error, such as when `None` is unwrapped. +When multiple failure points may exist, an `Option` can be replaced by the +more general `Result` type. A `Result` has these variants: * `Ok`: An element `T` was found * `Err`: An error was found with element `E` @@ -12,8 +11,8 @@ Similar to `Option`, `Result` also contains the `unwrap()` method which yields t {result.play} -Clearly, panicking on an `Err` leaves an unhelpful error message. Do we even know anything -about libcore that the error is telling us all about? There must be a better way. +Clearly, panicking on an `Err` leaves an unhelpful error message. Luckily for us, +the upcoming combinators are available to help us with errors. ### See also: diff --git a/examples/error/result/result.rs b/examples/error/result/result.rs index 0307602d91..9d98ebfba1 100644 --- a/examples/error/result/result.rs +++ b/examples/error/result/result.rs @@ -1,7 +1,7 @@ fn double_number(number_str: &str) -> i32 { - // It might not always be possible to parse a string into the other type + // It might not always be possible to parse a string into the other type, // so `parse()` returns a `Result` indicating possible failure. Let's - // just try `unwrap()` to get the number out. Will it bite us? + // try using `unwrap()` to get the number out. Will it bite us? 2 * number_str.parse::().unwrap() } From 867707ea335b1e6cd6a39aa965b6b1637d709fa7 Mon Sep 17 00:00:00 2001 From: aakloxu Date: Sat, 30 Apr 2016 08:23:37 +0800 Subject: [PATCH 0457/1122] Update input.md remove dead link and add the correct link --- .../flow_control/match/destructuring/destructure_enum/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index b39e0bc8cf..9f6a352ed9 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -7,7 +7,7 @@ An `enum` is destructured similarly: [`#[allow(...)]`][allow], [color models][color_models], [`enum`][enum], and [`#[derive(...)]`][derive] -[allow]: /fn/unused.html +[allow]: /attribute/unused.html [color_models]: http://en.wikipedia.org/wiki/Color_model [derive]: /trait/derive.html [enum]: /custom_types/enum.html From caeaa8871c6ac708fd630c0e5b1c6adfc1ae2248 Mon Sep 17 00:00:00 2001 From: Joe Miyamoto Date: Sat, 30 Apr 2016 16:31:11 +0900 Subject: [PATCH 0458/1122] add link to Japanese translation --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 319c7c7e91..a24598f8ff 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,10 @@ license. See LICENSE-APACHE and LICENSE-MIT for more details. +## Translation to another languages + +[Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) + [travis-image]: https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master [travis-link]: https://travis-ci.org/rust-lang/rust-by-example [website]: http://rustbyexample.com From 01fd175eaea213ffb85e5fad03aee556df70fd8a Mon Sep 17 00:00:00 2001 From: Jack Danger Canty Date: Sun, 1 May 2016 11:56:13 -0700 Subject: [PATCH 0459/1122] Adding semicolons to println example Copying and pasting these lines results in a compilation error unless semicolons are added. This wasn't immediately obvious from the error message. --- examples/primitives/tuples/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/primitives/tuples/input.md b/examples/primitives/tuples/input.md index 1a4f0c8bf5..a4da7c7857 100644 --- a/examples/primitives/tuples/input.md +++ b/examples/primitives/tuples/input.md @@ -19,8 +19,8 @@ use tuples to return multiple values, as tuples can hold any number of values. accepts a matrix as an argument, and returns a matrix in which two elements have been swapped. For example: ``` -println!("Matrix:\n{}", matrix) -println!("Transpose:\n{}", transpose(matrix)) +println!("Matrix:\n{}", matrix); +println!("Transpose:\n{}", transpose(matrix)); ``` results in the output: ``` From dec19839b59d2fc6801413fd581932cd976c7a6a Mon Sep 17 00:00:00 2001 From: Jack Danger Canty Date: Sun, 1 May 2016 12:36:35 -0700 Subject: [PATCH 0460/1122] =?UTF-8?q?Diversifying=20enum=20person=20exampl?= =?UTF-8?q?es=20=E2=80=93=20custom=5Ftypes/enum.html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was struck when working through this example that the "fat"/"skinny" dichotomy was a little distracting. I changed that to "Engineer"/"Scientist" and I renamed the example people from all white males to a slightly more interesting set of names. --- examples/custom_types/enum/enum.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/custom_types/enum/enum.rs b/examples/custom_types/enum/enum.rs index e7807749be..ee57f2826d 100644 --- a/examples/custom_types/enum/enum.rs +++ b/examples/custom_types/enum/enum.rs @@ -3,12 +3,12 @@ // Create an `enum` to classify someone. Note how both names // and type information together specify the variant: -// `Skinny != Fat` and `Height(i32) != Weight(i32)`. Each +// `Engineer != Scientist` and `Height(i32) != Weight(i32)`. Each // is different and independent. enum Person { // An `enum` may either be `unit-like`, - Skinny, - Fat, + Engineer, + Scientist, // like tuple structs, Height(i32), Weight(i32), @@ -22,8 +22,8 @@ fn inspect(p: Person) { // Usage of an `enum` must cover all cases (irrefutable) // so a `match` is used to branch over it. match p { - Person::Skinny => println!("Is skinny!"), - Person::Fat => println!("Is fat!"), + Person::Engineer => println!("Is an engineer!"), + Person::Scientist => println!("Is a scientist!"), // Destructure `i` from inside the `enum`. Person::Height(i) => println!("Has a height of {}.", i), Person::Weight(i) => println!("Has a weight of {}.", i), @@ -35,16 +35,16 @@ fn inspect(p: Person) { } fn main() { - let person = Person::Height(18); - let danny = Person::Weight(10); + let person = Person::Height(18); + let amira = Person::Weight(10); // `to_owned()` creates an owned `String` from a string slice. - let dave = Person::Info { name: "Dave".to_owned(), height: 72 }; - let john = Person::Fat; - let larry = Person::Skinny; + let dave = Person::Info { name: "Dave".to_owned(), height: 72 }; + let rebecca = Person::Scientist; + let rohan = Person::Engineer; inspect(person); - inspect(danny); + inspect(amira); inspect(dave); - inspect(john); - inspect(larry); + inspect(rebecca); + inspect(rohan); } From 89ccf7ba748ebfdf3aff04de9ed541541c905932 Mon Sep 17 00:00:00 2001 From: Jack Danger Canty Date: Sun, 1 May 2016 21:31:52 -0700 Subject: [PATCH 0461/1122] Moving macro section to after traits None of the macros were useful without understanding the basics first and some of the more complex examples introduced such advanced concepts as trait restrictions on generics. A new Rustacean needs to learn about traits and scope and ownership before they can learn macros. --- examples/structure.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/structure.json b/examples/structure.json index 6364343951..cc7a0f4eba 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -69,12 +69,6 @@ ] }, { "id": "hof", "title": "Higher Order Functions", "children": null } ] }, - { "id": "macros", "title": "macro_rules!", "children": [ - { "id": "designators", "title": "Designators", "children": null }, - { "id": "overload", "title": "Overload", "children": null }, - { "id": "repeat", "title": "Repeat", "children": null }, - { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } - ] }, { "id": "mod", "title": "Modules", "children": [ { "id": "visibility", "title": "Visibility", "children": null }, { "id": "struct_visibility", "title": "Struct visibility", "children": null }, @@ -139,6 +133,12 @@ { "id": "iter", "title": "Iterators", "children": null }, { "id": "clone", "title": "Clone", "children": null } ] }, + { "id": "macros", "title": "macro_rules!", "children": [ + { "id": "designators", "title": "Designators", "children": null }, + { "id": "overload", "title": "Overload", "children": null }, + { "id": "repeat", "title": "Repeat", "children": null }, + { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } + ] }, { "id": "error", "title": "Error handling", "children": [ { "id": "unwrap", "title": "Option & unwrap", "children": null }, { "id": "map", "title": "map", "children": null }, From 659c6cf5563923a8500744f40304f3725994ec72 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 3 May 2016 17:27:38 -0700 Subject: [PATCH 0462/1122] Updated and restructured Ch16.5, 16.6 Readability and grammar changes Renamed "Result as an alias" to "aliases for Result" Made "map for Result" and "aliases for Result" into children of "Result" --- examples/error/result/result_alias/alias.rs | 23 ++++++++++++++++++ examples/error/result/result_alias/input.md | 18 ++++++++++++++ examples/error/result/result_map/input.md | 24 +++++++++++++++++++ .../error/{ => result}/result_map/result.rs | 12 +++++----- examples/error/result_alias/alias.rs | 23 ------------------ examples/error/result_alias/input.md | 16 ------------- examples/error/result_map/input.md | 21 ---------------- examples/structure.json | 7 +++--- 8 files changed, 75 insertions(+), 69 deletions(-) create mode 100644 examples/error/result/result_alias/alias.rs create mode 100644 examples/error/result/result_alias/input.md create mode 100644 examples/error/result/result_map/input.md rename examples/error/{ => result}/result_map/result.rs (66%) delete mode 100644 examples/error/result_alias/alias.rs delete mode 100644 examples/error/result_alias/input.md delete mode 100644 examples/error/result_map/input.md diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs new file mode 100644 index 0000000000..e3113ac3fe --- /dev/null +++ b/examples/error/result/result_alias/alias.rs @@ -0,0 +1,23 @@ +use std::num::ParseIntError; +use std::result; + +// Define a generic alias for a `Result` of type `ParseIntError`. +type AliasedResult = result::Result; + +// Use the alias defined above to refer to our specific `Result` type. +fn double_number(number_str: &str) -> AliasedResult { + number_str.parse::().map(|n| 2 * n) +} + +// Here, the alias again allows us to save some space. +fn print(result: AliasedResult) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + print(double_number("10")); + print(double_number("t")); +} diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md new file mode 100644 index 0000000000..2f8175737c --- /dev/null +++ b/examples/error/result/result_alias/input.md @@ -0,0 +1,18 @@ +How about when we want to reuse a specific `Result` type many times? +It quickly becomes tedious to write out the full type name, but recall that Rust allows +us to create [aliases][alias]. A generic alias may conveniently be defined for the +specific `Result` in question: + +{alias.play} + +At a module level, creating aliases can be particularly helpful. Errors +found in a specific module often have the same `Err` type, so a single alias can succinctly +define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[alias]: /cast/alias.html +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md new file mode 100644 index 0000000000..00641072a5 --- /dev/null +++ b/examples/error/result/result_map/input.md @@ -0,0 +1,24 @@ +Panicking on `unwrap()` in the previous example gave us an unhelpful error message. +To avoid that, we need to be more specific about the return type. In that example, +recall that the regular element is of type `i32`. To determine the `Err` type, we +look to `parse()`. `parse()` is implemented with the [`FromStr trait`][from_str] +for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. + +In the example below, note that using the straightforward `match` statement leads to +more cumbersome code. As it turns out, the `map` method we used with `Option` +is also implemented for `Result`. + +{result.play} + +Much like `Option`, `Result` implements combinators besides `map`, such as `and_then` +and `unwrap_or`. This even includes those that specifically handle errors, like `map_err`. +[`Result`][result] contains the complete listing. + +### See also: + +[`i32`][i32], [`FromStr`][from_str], and [`ParseIntErr`][parse_int_error] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html +[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html +[i32]: http://doc.rust-lang.org/std/primitive.i32.html diff --git a/examples/error/result_map/result.rs b/examples/error/result/result_map/result.rs similarity index 66% rename from examples/error/result_map/result.rs rename to examples/error/result/result_map/result.rs index 6f7a741837..bb009b24c2 100644 --- a/examples/error/result_map/result.rs +++ b/examples/error/result/result_map/result.rs @@ -1,8 +1,7 @@ use std::num::ParseIntError; // With the return type rewritten, we proceed to use pattern matching without -// `unwrap()` but it is tedious. Couldn't a combinator like in the `Option` -// example also be used here? Yes. +// `unwrap()`, but it is tedious. fn double_number(number_str: &str) -> Result { match number_str.parse::() { Ok(n) => Ok(2 * n), @@ -10,8 +9,9 @@ fn double_number(number_str: &str) -> Result { } } -// The exact same but written with `map()`. Modify if the value is valid, -// otherwise pass the error on. +// As with `Option`, we can use combinators such as `map()`. +// This function is otherwise identical to the one above and reads: +// Modify n if the value is valid, otherwise pass on the error. fn double_number_map(number_str: &str) -> Result { number_str.parse::().map(|n| 2 * n) } @@ -24,11 +24,11 @@ fn print(result: Result) { } fn main() { - // Still presents a reasonable answer. + // This still presents a reasonable answer. let twenty = double_number("10"); print(twenty); - // This is now much better than before with the messy `panic`. + // The following now provides a much more useful error message let tt = double_number_map("t"); print(tt); } diff --git a/examples/error/result_alias/alias.rs b/examples/error/result_alias/alias.rs deleted file mode 100644 index dd9a8ade10..0000000000 --- a/examples/error/result_alias/alias.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::num::ParseIntError; -use std::result; - -// A generic alias for any `Result` with this specific `Err` type. -type Result = result::Result; - -// Use the alias defined above referring to our specific `Result` type. -fn double_number(number_str: &str) -> Result { - number_str.parse::().map(|n| 2 * n) -} - -// Again, the alias saved us from defining it again. -fn print(result: Result) { - match result { - Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - print(double_number("10")); - print(double_number("t")); -} diff --git a/examples/error/result_alias/input.md b/examples/error/result_alias/input.md deleted file mode 100644 index cb4657b974..0000000000 --- a/examples/error/result_alias/input.md +++ /dev/null @@ -1,16 +0,0 @@ -What if the specific `Result` type is reused many many times? Then quickly it becomes tedious -to write out the full type name. Instead, a generic alias for the specific `Result` may be -defined. - -{alias.play} - -This is particularly helpful at a module level because all errors found in a specific module -may have the same `Err` type; a single alias succinctly defines *all* module `Results`. This -is so useful that the std library even supplies one: `io::Result` which refers to IO errors. - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result_map/input.md b/examples/error/result_map/input.md deleted file mode 100644 index 6af4fcbc89..0000000000 --- a/examples/error/result_map/input.md +++ /dev/null @@ -1,21 +0,0 @@ -To avoid the `unwrap()` in the previous example, we will have to rewrite the example to be -specific about what type it returns. In this case, the regular element should definitely -be `i32` but what about the `Err` type? Well, `parse()` is implemented with the -[`FromStr trait`][from_str] for [`i32`][i32]. That implementation specifies the -`Err` type as [`ParseIntError`][parse_int_error]. - -{result.play} - -Similar to `Option`, `Result` has many other combinators besides `map` such as `and_then` -and `unwrap_or`; even ones to handle the errors specifically such as `map_err`. -`Result` contains the complete listing. - -### See also: - -[`i32`][i32], [`FromStr`][from_str], [`ParseIntErr`][parse_int_error], and -[`Result`][result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html -[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html -[i32]: http://doc.rust-lang.org/std/primitive.i32.html diff --git a/examples/structure.json b/examples/structure.json index 6364343951..00ac357d9b 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -143,9 +143,10 @@ { "id": "unwrap", "title": "Option & unwrap", "children": null }, { "id": "map", "title": "map", "children": null }, { "id": "and_then", "title": "and_then", "children": null }, - { "id": "result", "title": "Result", "children": null }, - { "id": "result_map", "title": "map for Result", "children": null }, - { "id": "result_alias", "title": "Result as an alias", "children": null }, + { "id": "result", "title": "Result", "children": [ + { "id": "result_map", "title": "map for Result", "children": null }, + { "id": "result_alias", "title": "aliases for Result", "children": null }, + ] }, { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Errors as strings", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, From 764275a00f28377ace46ce4c9d3e268929d465dd Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 3 May 2016 19:13:22 -0700 Subject: [PATCH 0463/1122] Remove trailing comma --- examples/structure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index 00ac357d9b..29361bf7c9 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -145,7 +145,7 @@ { "id": "and_then", "title": "and_then", "children": null }, { "id": "result", "title": "Result", "children": [ { "id": "result_map", "title": "map for Result", "children": null }, - { "id": "result_alias", "title": "aliases for Result", "children": null }, + { "id": "result_alias", "title": "aliases for Result", "children": null } ] }, { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Errors as strings", "children": null }, From 7f269168289c7346cbb4e0958a13c1ca9a75468b Mon Sep 17 00:00:00 2001 From: aakloxu Date: Wed, 4 May 2016 15:48:38 +0800 Subject: [PATCH 0464/1122] Add link to Chinese translation --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a24598f8ff..3ebf3e6dcb 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,11 @@ The Makefile provides the following recipes: under `localhost:4000` * `make test`: will check all the rust source files for compilation errors +## Translation to another languages + +* [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) +* [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) + ## License Rust by Example is dual-licensed under the Apache 2.0 license and the MIT @@ -104,10 +109,6 @@ license. See LICENSE-APACHE and LICENSE-MIT for more details. -## Translation to another languages - -[Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) - [travis-image]: https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master [travis-link]: https://travis-ci.org/rust-lang/rust-by-example [website]: http://rustbyexample.com From b46e4e68f50589decea9a6796910997399d5720c Mon Sep 17 00:00:00 2001 From: aakloxu Date: Thu, 5 May 2016 00:22:46 +0800 Subject: [PATCH 0465/1122] Fixed expression errors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ebf3e6dcb..1f8811573b 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The Makefile provides the following recipes: under `localhost:4000` * `make test`: will check all the rust source files for compilation errors -## Translation to another languages +## Translations to other languages * [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) * [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) From 5147bdf4e791ea7f517377c39f169fcdefb280e8 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 4 May 2016 16:51:58 -0700 Subject: [PATCH 0466/1122] Added changes from PR "of type" -> "with the error type" [alias] -> [typealias] --- examples/error/result/result_alias/alias.rs | 2 +- examples/error/result/result_alias/input.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs index e3113ac3fe..105f1ebe42 100644 --- a/examples/error/result/result_alias/alias.rs +++ b/examples/error/result/result_alias/alias.rs @@ -1,7 +1,7 @@ use std::num::ParseIntError; use std::result; -// Define a generic alias for a `Result` of type `ParseIntError`. +// Define a generic alias for a `Result` with the error type `ParseIntError`. type AliasedResult = result::Result; // Use the alias defined above to refer to our specific `Result` type. diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md index 2f8175737c..9d2e67c311 100644 --- a/examples/error/result/result_alias/input.md +++ b/examples/error/result/result_alias/input.md @@ -1,6 +1,6 @@ How about when we want to reuse a specific `Result` type many times? It quickly becomes tedious to write out the full type name, but recall that Rust allows -us to create [aliases][alias]. A generic alias may conveniently be defined for the +us to create [aliases][typealias]. A generic alias may conveniently be defined for the specific `Result` in question: {alias.play} @@ -13,6 +13,6 @@ define *all* associated `Results`. This is so useful that the `std` library even [`Result`][result] and [`io::Result`][io_result] -[alias]: /cast/alias.html +[typealias]: /cast/alias.html [result]: http://doc.rust-lang.org/std/result/enum.Result.html [io_result]: http://doc.rust-lang.org/std/io/type.Result.html From 16501c02b24f0903b57dff6620a370a961f0973d Mon Sep 17 00:00:00 2001 From: arvidj Date: Sat, 14 May 2016 10:55:45 +0200 Subject: [PATCH 0467/1122] Add activity as per #752 --- .../hello/print/print_display/testcase_list/input.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/hello/print/print_display/testcase_list/input.md b/examples/hello/print/print_display/testcase_list/input.md index 61ad10532b..1fe3f783f9 100644 --- a/examples/hello/print/print_display/testcase_list/input.md +++ b/examples/hello/print/print_display/testcase_list/input.md @@ -16,6 +16,15 @@ straightforward: {testcase_list.play} +### Activity + +Try changing to program so that the index of each element in the vector is also printed. The new output should look like this: + +``` +[0: 10, 1: 40, 2: 30]. +``` + + ### See also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], From 3800e7165f853b5fddac52fbb647f72a7ab1535c Mon Sep 17 00:00:00 2001 From: arvidj Date: Sat, 14 May 2016 18:06:02 +0200 Subject: [PATCH 0468/1122] Fixes in new activity for testcase_list --- examples/hello/print/print_display/testcase_list/input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/hello/print/print_display/testcase_list/input.md b/examples/hello/print/print_display/testcase_list/input.md index 1fe3f783f9..6db364e40d 100644 --- a/examples/hello/print/print_display/testcase_list/input.md +++ b/examples/hello/print/print_display/testcase_list/input.md @@ -18,10 +18,10 @@ straightforward: ### Activity -Try changing to program so that the index of each element in the vector is also printed. The new output should look like this: +Try changing the program so that the index of each element in the vector is also printed. The new output should look like this: -``` -[0: 10, 1: 40, 2: 30]. +```rust +[0: 1, 1: 2, 2: 3] ``` From d4c36052e881b19391c917decfa40345630a9e13 Mon Sep 17 00:00:00 2001 From: arvidj Date: Sat, 14 May 2016 18:39:06 +0200 Subject: [PATCH 0469/1122] Remove exception about isize/usize and add example #742 --- examples/cast/literals/input.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/cast/literals/input.md b/examples/cast/literals/input.md index 26c74d8b38..08956a43c6 100644 --- a/examples/cast/literals/input.md +++ b/examples/cast/literals/input.md @@ -1,6 +1,5 @@ -Numeric literals can be type annotated by adding the type as a suffix, with the -exception of `usize` that uses the `usize` suffix and `isize` that uses the -`isize` suffix. +Numeric literals can be type annotated by adding the type as a suffix. As an example, +to specify that the literal `42` should have the type `i32`, write `42i32`. The type of unsuffixed numeric literals will depend on how they are used. If no constraint exists, the compiler will use `i32` for integers, and `f64` for From 7bbf9dbcb70255504d1e5116c9d47f32f5c3d2d8 Mon Sep 17 00:00:00 2001 From: arvidj Date: Tue, 17 May 2016 22:52:49 +0200 Subject: [PATCH 0470/1122] custom_types/structs.html: add activities --- examples/custom_types/structs/input.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/custom_types/structs/input.md b/examples/custom_types/structs/input.md index 5dc15ecef6..071d20883e 100644 --- a/examples/custom_types/structs/input.md +++ b/examples/custom_types/structs/input.md @@ -7,6 +7,12 @@ There are three types of structures ("structs") that can be created using the {structs.play} +### Activity + +1. Add a function `rect_area` which calculates the area of a rectangle (try + using nested destructuring). +2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`. + ### See also: [`attributes`][attributes] and [destructuring][destructuring] From b1ddd4eb6db163d8fe4f453beb167c5831a6be48 Mon Sep 17 00:00:00 2001 From: arvidj Date: Tue, 17 May 2016 23:13:00 +0200 Subject: [PATCH 0471/1122] cast/cast.rs: try to clear up two's complement #741 Not sure if this is the ideal way to explain either, but perhaps a little less confusing than the original explanation. Also improve the wording of MSB/LSB. --- examples/cast/cast.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/cast/cast.rs b/examples/cast/cast.rs index 59db9eede0..b91f8025df 100644 --- a/examples/cast/cast.rs +++ b/examples/cast/cast.rs @@ -22,7 +22,7 @@ fn main() { println!("1000 as a u16 is: {}", 1000 as u16); // 1000 - 256 - 256 - 256 = 232 - // Under the hood, the first 8 bits from the least significant bit (LSB) are used, + // Under the hood, the first 8 least significant bits (LSB) are kept, // while the rest towards the most significant bit (MSB) get truncated. println!("1000 as a u8 is : {}", 1000 as u8); // -1 + 256 = 255 @@ -31,9 +31,9 @@ fn main() { // For positive numbers, this is the same as the modulus println!("1000 mod 256 is : {}", 1000 % 256); - // When casting to a signed type, the result is the same as - // first casting to the corresponding unsigned type then - // taking the two's complement. + // When casting to a signed type, the (bitwise) result is the same as + // first casting to the corresponding unsigned type. If the most significant + // bit of that value is 1, then the value is negative. // Unless it already fits, of course. println!(" 128 as a i16 is: {}", 128 as i16); From 2d11de62ece6625cd2eee240fcb0522c9c729266 Mon Sep 17 00:00:00 2001 From: joemphilips Date: Wed, 18 May 2016 21:30:32 +0900 Subject: [PATCH 0472/1122] delete match/struct --- examples/flow_control/match/struct/input.md | 9 -------- examples/flow_control/match/struct/struct.rs | 22 -------------------- 2 files changed, 31 deletions(-) delete mode 100644 examples/flow_control/match/struct/input.md delete mode 100644 examples/flow_control/match/struct/struct.rs diff --git a/examples/flow_control/match/struct/input.md b/examples/flow_control/match/struct/input.md deleted file mode 100644 index c65ae271d8..0000000000 --- a/examples/flow_control/match/struct/input.md +++ /dev/null @@ -1,9 +0,0 @@ -A `struct` can be destructured with pattern matching. - -{struct.play} - -### See also: - -[`struct`][structs] - -[structs]: /structs.html diff --git a/examples/flow_control/match/struct/struct.rs b/examples/flow_control/match/struct/struct.rs deleted file mode 100644 index 224f583deb..0000000000 --- a/examples/flow_control/match/struct/struct.rs +++ /dev/null @@ -1,22 +0,0 @@ -fn main() { - struct Foo { x: (u32, u32), y: u32 } - - // destructure members of the struct - let foo = Foo { x: (1, 2), y: 3 }; - let Foo { x: (a, b), y } = foo; - - println!("a = {}, b = {}, y = {} ", a, b, y); - - // you can destructure structs and rename the variables, - // the order is not important - - let Foo { y: i, x: j } = foo; - println!("i = {:?}, j = {:?}", i, j); - - // and you can also ignore some variables: - let Foo { y, .. } = foo; - println!("y = {}", y); - - // this will give an error: pattern does not mention field `x` - // let Foo { y } = foo; -} From b7c93874eb2cd8925c4d2a36fcf8cfed648f467f Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Mon, 23 May 2016 18:05:30 -0400 Subject: [PATCH 0473/1122] Use method syntax when getting the description of an error --- examples/std_misc/file/create/create.rs | 4 ++-- examples/std_misc/file/open/open.rs | 4 ++-- examples/std_misc/process/pipe/pipe.rs | 6 +++--- src/markdown.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/std_misc/file/create/create.rs b/examples/std_misc/file/create/create.rs index 9e6bd870a1..4fd64ff022 100644 --- a/examples/std_misc/file/create/create.rs +++ b/examples/std_misc/file/create/create.rs @@ -20,7 +20,7 @@ fn main() { let mut file = match File::create(&path) { Err(why) => panic!("couldn't create {}: {}", display, - Error::description(&why)), + why.description()), Ok(file) => file, }; @@ -28,7 +28,7 @@ fn main() { match file.write_all(LOREM_IPSUM.as_bytes()) { Err(why) => { panic!("couldn't write to {}: {}", display, - Error::description(&why)) + why.description()) }, Ok(_) => println!("successfully wrote to {}", display), } diff --git a/examples/std_misc/file/open/open.rs b/examples/std_misc/file/open/open.rs index 79eb46074d..d97517cd39 100644 --- a/examples/std_misc/file/open/open.rs +++ b/examples/std_misc/file/open/open.rs @@ -13,7 +13,7 @@ fn main() { // The `description` method of `io::Error` returns a string that // describes the error Err(why) => panic!("couldn't open {}: {}", display, - Error::description(&why)), + why.description()), Ok(file) => file, }; @@ -21,7 +21,7 @@ fn main() { let mut s = String::new(); match file.read_to_string(&mut s) { Err(why) => panic!("couldn't read {}: {}", display, - Error::description(&why)), + why.description()), Ok(_) => print!("{} contains:\n{}", display, s), } diff --git a/examples/std_misc/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs index 98e112e127..fa33e845a5 100644 --- a/examples/std_misc/process/pipe/pipe.rs +++ b/examples/std_misc/process/pipe/pipe.rs @@ -11,7 +11,7 @@ fn main() { .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() { - Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)), + Err(why) => panic!("couldn't spawn wc: {}", why.description()), Ok(process) => process, }; @@ -21,7 +21,7 @@ fn main() { // must have one, we can directly `unwrap` it. match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { Err(why) => panic!("couldn't write to wc stdin: {}", - Error::description(&why)), + why.description()), Ok(_) => println!("sent pangram to wc"), } @@ -35,7 +35,7 @@ fn main() { let mut s = String::new(); match process.stdout.unwrap().read_to_string(&mut s) { Err(why) => panic!("couldn't read wc stdout: {}", - Error::description(&why)), + why.description()), Ok(_) => print!("wc responded with:\n{}", s), } } diff --git a/src/markdown.rs b/src/markdown.rs index effaa63d4b..5ab916453b 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -170,6 +170,6 @@ impl<'a, 'b> Markdown<'a, 'b> { let path = Path::new(path_str); file::write(&path, &self.content) - .map_err(|ref e| Error::description(e).to_string()) + .map_err(|ref e| e.description().to_string()) } } From fdd248bf00e295840e2ce3f6e4c8e2f18f093537 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 4 May 2016 15:17:36 -0700 Subject: [PATCH 0474/1122] Update Ch16.7 Options with Results Reword much of the page for clarity Reword example code to be more specific Removed unnecessary See Also links --- examples/error/option_with_result/input.md | 24 +++++++++---------- .../error/option_with_result/option_result.rs | 13 ++++++---- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/examples/error/option_with_result/input.md b/examples/error/option_with_result/input.md index de52492598..e1112363b8 100644 --- a/examples/error/option_with_result/input.md +++ b/examples/error/option_with_result/input.md @@ -1,16 +1,16 @@ -The previous examples have always been very convenient; a `Result` interacts with the same -`Results` and an `Option` with the same `Option`. Sometimes it is not this easy though; -`Options` and `Results` may have to interact or even `Result` with -`Result`. +In the following sections, we will see how to combine separate operations returning +`Option` and `Result` into a single operation that returns whichever one makes the +most sense. -Here is an example where one returns an `Option` and the other returns an `Result`. Aside -from messy errors provided by `unwrap`, this looks reasonable: +The previous examples have always been very convenient; a `Result` interacted +with another `Result` and an `Option` interacted with another `Option`. Unfortunately, +it's not always that easy. An `Option` may have to interact with a `Result`, and a +`Result` may have to interact with a `Result`. -{option_result.play} - -### See also: +To start us off, the example below uses `Vec::first` and `parse::` with `unwrap` to +generate errors. `Vec::first` returns an `Option`, while `parse::` +returns a `Result`. -[`Result`][result] and [`io::Result`][io_result] +Note that this code "works", but is meant to showcase **improper** error handling: -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +{option_result.play} diff --git a/examples/error/option_with_result/option_result.rs b/examples/error/option_with_result/option_result.rs index e6c34801f5..5d13f054c1 100644 --- a/examples/error/option_with_result/option_result.rs +++ b/examples/error/option_with_result/option_result.rs @@ -1,10 +1,9 @@ -// The first attempt conveniently uses `unwrap` with the aforementioned -// bad errors it results in. +// Our first attempt uses `unwrap` and provides unhelpful errors. fn double_first(vec: Vec<&str>) -> i32 { - // What if the vector is empty? + // Returns an error if the input vector is empty: let first = vec.first().unwrap(); - // What if the element doesn't parse to a number? + // Returns an error if the element doesn't parse to a number: 2 * first.parse::().unwrap() } @@ -14,7 +13,11 @@ fn main() { let strings = vec!["tofu", "93", "18"]; println!("The first doubled is {}", double_first(numbers)); + + // This line results in the first error: println!("The first doubled is {}", double_first(empty)); - // ^ Comment out this line to see the second error. + // ^ Comment this out to see the second error. + + // This line results in a second error: println!("The first doubled is {}", double_first(strings)); } From e9360e2f28a878ed3e09da9e7f88c542c969fc74 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 4 May 2016 16:06:41 -0700 Subject: [PATCH 0475/1122] Rename Ch16.7.1 Renamed "Errors as strings" to "Strings as errors" for consistency with text in other sections --- examples/structure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index ad1df779b8..dbaedc98a0 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -148,7 +148,7 @@ { "id": "result_alias", "title": "aliases for Result", "children": null } ] }, { "id": "option_with_result", "title": "Options with Results", "children": [ - { "id": "result_string_errors", "title": "Errors as strings", "children": null }, + { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, { "id": "enter_try", "title": "Enter try!", "children": null } ] }, From d451114d942247968b531d46c02644629b64a919 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 4 May 2016 16:07:57 -0700 Subject: [PATCH 0476/1122] Update Ch16.7.1 Reduce the number of questions being asked (to provide more information) Reword for clarity and flow with respect to rest of chapter --- .../result_string_errors/input.md | 22 +++++++------------ .../result_string_errors/result_string.rs | 13 ++++++----- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/examples/error/option_with_result/result_string_errors/input.md b/examples/error/option_with_result/result_string_errors/input.md index 5c9f47b3f6..e2a6de3d3d 100644 --- a/examples/error/option_with_result/result_string_errors/input.md +++ b/examples/error/option_with_result/result_string_errors/input.md @@ -1,17 +1,11 @@ -Eliminating `unwrap` from the previous example requires more care. The two types in play -being `Option` and `Result`, one valid approach would be to convert both into a `Result` -with a common `Err` type. We will try it with `Err(String)` which seems like a nice first -approximation: +From our previous example, one method of solving our issue with `unwrap` is to remove it. +In doing so, we must move from implicit to explicit error handling. Since the only +types in play are `Option` and `Result`, we can consider converting both into +`Result`s with the same `Err` type. For our first attempt at this solution, +let's try using a `String` for our error: {result_string.play} -This is not too bad but it is hardly as nice as the original (it can still be nicer but -we are not there yet). The question is, does this approach scale well. Consider the next -example. - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +This is not too bad, but it is hardly as nice as the original (it can still be nicer but +we are not there yet). Unfortunately, this approach scales poorly with increasing +numbers of `Result`s, as will be seen in the next example. diff --git a/examples/error/option_with_result/result_string_errors/result_string.rs b/examples/error/option_with_result/result_string_errors/result_string.rs index dbf9fa85c8..abda6a654f 100644 --- a/examples/error/option_with_result/result_string_errors/result_string.rs +++ b/examples/error/option_with_result/result_string_errors/result_string.rs @@ -1,16 +1,17 @@ +// Use `String` as our error type type Result = std::result::Result; fn double_first(vec: Vec<&str>) -> Result { vec.first() - // Convert the `Option` to a `Result` if there is a value; otherwise - // use an `Err` containing this `String`. + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. .ok_or("Please use a vector with at least one element.".to_owned()) - // `parse` returns a `Result`. + // Recall that `parse` returns a `Result`. .and_then(|s| s.parse::() - // The return type is `Result`. We need - // to map only the errors `parse` yields to `String`. + // Map the errors `parse` yields to `String`. + // The return type is then `Result`. .map_err(|e| e.to_string()) - // Apply the double to the number inside. + // At this point, we can double the number inside. .map(|i| 2 * i)) } From 3bb36a997643d4f3dd13c5af2a4c3b6ce3d9ee04 Mon Sep 17 00:00:00 2001 From: Aaklo Xu Date: Sat, 28 May 2016 22:29:51 +0800 Subject: [PATCH 0477/1122] Fix dead link --- examples/scope/borrow/mut/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/scope/borrow/mut/input.md b/examples/scope/borrow/mut/input.md index ed07ed1c2e..96ce5325bf 100644 --- a/examples/scope/borrow/mut/input.md +++ b/examples/scope/borrow/mut/input.md @@ -5,7 +5,7 @@ the borrower can read the data but not modify it: {mut.play} -### See Also +### See also: [`static`][static] -[static]: scope/lifetime/static_lifetime.html +[static]: /scope/lifetime/static_lifetime.html From 8a4f5b1b5a2ddaa5a369c49e177032692cd02a0c Mon Sep 17 00:00:00 2001 From: Aaklo Xu Date: Sun, 29 May 2016 21:15:41 +0800 Subject: [PATCH 0478/1122] Fix a link --- examples/scope/borrow/mut/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/borrow/mut/input.md b/examples/scope/borrow/mut/input.md index 96ce5325bf..1482aff079 100644 --- a/examples/scope/borrow/mut/input.md +++ b/examples/scope/borrow/mut/input.md @@ -8,4 +8,4 @@ the borrower can read the data but not modify it: ### See also: [`static`][static] -[static]: /scope/lifetime/static_lifetime.html +[static]: ../lifetime/static_lifetime.html From eefbaab8e2c97a4259db1668887e8b7f10d2504b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 16 Jun 2016 15:40:44 -0700 Subject: [PATCH 0479/1122] Reworked activity 2 As suggested in issue #761 --- examples/hello/print/input.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index e83d5d9259..6cf2945e05 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -24,8 +24,9 @@ for these types. To print text for custom types, more steps are required. * Fix the two issues in the above code (see FIXME) so that it runs without error. - * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two - divided by seven to generate the estimate for Pi. (Hint: you may need to + * Add a `println!` macro that prints: `Pi is roughly 3.142` by controlling + the number of decimal places shown. For the purposes of this exercise, + use `let pi = 3.141592` as an estimate for Pi. (Hint: you may need to check the [`std::fmt`][fmt] documentation for setting the number of decimals to display) From 0663a6c902e13e27f791c647653c5ea02ac905ab Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 16 Jun 2016 15:47:52 -0700 Subject: [PATCH 0480/1122] Address issue #740 Added `#[allow(dead_code)]` to prevent the warning message after reader addresses `FIXME` issues --- examples/hello/print/print.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs index ee51db8ab7..303adddb79 100644 --- a/examples/hello/print/print.rs +++ b/examples/hello/print/print.rs @@ -32,6 +32,7 @@ fn main() { // FIXME ^ Add the missing argument: "James" // Create a structure which contains an `i32`. Name it `Structure`. + #[allow(dead_code)] struct Structure(i32); // However, custom types such as this structure require more complicated From 436ce5f86998756cdd3b576538eb6a8344c1c01f Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 16 Jun 2016 16:02:02 -0700 Subject: [PATCH 0481/1122] Partial fix for issue #706 Added `Copy` and 2 links to reference into derive page of RBE. --- examples/trait/derive/input.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index 4efc6513f3..94cb71f632 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -2,31 +2,29 @@ The compiler is capable of providing basic implementations for some traits via the `#[derive]` [attribute][attribute]. These traits can still be manually implemented if a more complex behavior is required. -The following is a list of the "derivable" traits: +The following is a list of derivable traits: * Comparison traits: - [`Eq`][eq], - [`PartialEq`][partial-eq], - [`Ord`][ord], - [`PartialOrd`][partial-ord] -* [`Clone`][clone], - to create `T` from `&T` via a copy. -* [`Hash`][hash], to - compute a hash from `&T`. -* [`Default`][default], - to create an empty instance of a data type. -* `Zero`, to - create a zero instance of a numeric data type. -* [`Debug`][debug], to - format a value using the `{:?}` formatter. - + [`Eq`][eq], [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord] +* [`Clone`][clone], to create `T` from `&T` via a copy. +* [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics' +* [`Hash`][hash], to compute a hash from `&T`. +* [`Default`][default], to create an empty instance of a data type. +* `Zero`, to create a zero instance of a numeric data type. +* [`Debug`][debug], to format a value using the `{:?}` formatter. + {derive.play} +### See also: +[`derive`][derive] + [attribute]: /attribute.html [eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html [partial-eq]: http://doc.rust-lang.org/std/cmp/trait.PartialEq.html [ord]: http://doc.rust-lang.org/std/cmp/trait.Ord.html [partial-ord]: http://doc.rust-lang.org/std/cmp/trait.PartialOrd.html [clone]: http://doc.rust-lang.org/std/clone/trait.Clone.html +[copy]: https://doc.rust-lang.org/core/marker/trait.Copy.html [hash]: http://doc.rust-lang.org/std/hash/trait.Hash.html [default]: http://doc.rust-lang.org/std/default/trait.Default.html [debug]: http://doc.rust-lang.org/std/fmt/trait.Debug.html +[derive]: https://doc.rust-lang.org/reference.html#derive From 92c6461f614db395aad7ee3dbef9435c48f022b7 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 16:19:54 -0700 Subject: [PATCH 0482/1122] Rename unwrap to option, Add panic_unwrap section New flow is: Error Handling -> Panic & Unwrap -> Option Renamed unwrap to option, as it still teaches that. Moved latter half of Error Handling intro into Panic & Unwrap. This shortens the introduction to Error handling and makes for more accessible information while browsing sections. --- examples/error/{unwrap => option}/input.md | 2 +- .../error/{unwrap/unwrap.rs => option/option.rs} | 0 examples/error/panic_unwrap/input.md | 16 ++++++++++++++++ examples/error/panic_unwrap/panic_unwrap.rs | 12 ++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) rename examples/error/{unwrap => option}/input.md (98%) rename examples/error/{unwrap/unwrap.rs => option/option.rs} (100%) create mode 100644 examples/error/panic_unwrap/input.md create mode 100644 examples/error/panic_unwrap/panic_unwrap.rs diff --git a/examples/error/unwrap/input.md b/examples/error/option/input.md similarity index 98% rename from examples/error/unwrap/input.md rename to examples/error/option/input.md index 119aaf1215..79cd7ad778 100644 --- a/examples/error/unwrap/input.md +++ b/examples/error/option/input.md @@ -16,6 +16,6 @@ meaningful output than explicit handling. In the following example, explicit handling yields a more controlled result while retaining the option to `panic` if desired. -{unwrap.play} +{option.play} [expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/unwrap/unwrap.rs b/examples/error/option/option.rs similarity index 100% rename from examples/error/unwrap/unwrap.rs rename to examples/error/option/option.rs diff --git a/examples/error/panic_unwrap/input.md b/examples/error/panic_unwrap/input.md new file mode 100644 index 0000000000..0dd1051892 --- /dev/null +++ b/examples/error/panic_unwrap/input.md @@ -0,0 +1,16 @@ +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Consider the following example: + +{panic_unwrap.play} + +This shows that we can induce program failure at will, but raises a +question: what happens if the princess is *not* given a gift? We *could* +explicitly test this with a check against the null string (`""`) as we do +with the snake, but this is not reliable. The problem is that programmers do +not habitually test these checks unless required to by the compiler. + +In order for this to be reliable, we'll want the compiler to point out +cases where there may not be a gift. In this chapter, we will learn to use +`Option` to take care of this condition, as well as various functions to +deal with the results of one or more uses of `Option`. diff --git a/examples/error/panic_unwrap/panic_unwrap.rs b/examples/error/panic_unwrap/panic_unwrap.rs new file mode 100644 index 0000000000..bb69620caa --- /dev/null +++ b/examples/error/panic_unwrap/panic_unwrap.rs @@ -0,0 +1,12 @@ +fn give_princess(gift: &str) { + // Princesses hate snakes, so we need to stop if + // she expresses her disapproval! + if gift == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", gift); +} + +fn main() { + give_princess("teddy bear"); + give_princess("snake"); +} From 9e83c60e578aded378563c38f1881a1c668130d6 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 16:21:35 -0700 Subject: [PATCH 0483/1122] Oops missed a spot Missed a file in last commit: 92c6461f614db395aad7ee3dbef9435c48f022b7 --- examples/structure.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index dbaedc98a0..fe80e2b35a 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,7 +140,8 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "unwrap", "title": "Option & unwrap", "children": null }, + { "id": "panic_unwrap", "title": "panic & unwrap", "children": null }, + { "id": "option", "title": "Option", "children": null }, { "id": "map", "title": "map", "children": null }, { "id": "and_then", "title": "and_then", "children": null }, { "id": "result", "title": "Result", "children": [ From a6c58d1185693f6cc5957c6bbb0257dfb1ab9f9e Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:46:36 -0700 Subject: [PATCH 0484/1122] Slight restructuring, revisions to chapter intro, relocate text on panic Moved intro to unwrap back to Option (now renamed to Option_unwrap) for better flow: Renamed panic_unwrap to panic. Renamed option to option_unwrap. Slight revisions to text on chapter intro. `map` and `and_then` sections are now children of `Option_unwrap`. "Combinators" added to title to better reflect content. --- examples/error/input.md | 17 ++---------- examples/error/option/input.md | 21 --------------- examples/error/option_unwrap/input.md | 27 +++++++++++++++++++ .../option_unwrap.rs} | 0 examples/error/panic/input.md | 5 ++++ .../panic_unwrap.rs => panic/panic.rs} | 0 examples/error/panic_unwrap/input.md | 16 ----------- examples/structure.json | 13 ++++----- 8 files changed, 41 insertions(+), 58 deletions(-) delete mode 100644 examples/error/option/input.md create mode 100644 examples/error/option_unwrap/input.md rename examples/error/{option/option.rs => option_unwrap/option_unwrap.rs} (100%) create mode 100644 examples/error/panic/input.md rename examples/error/{panic_unwrap/panic_unwrap.rs => panic/panic.rs} (100%) delete mode 100644 examples/error/panic_unwrap/input.md diff --git a/examples/error/input.md b/examples/error/input.md index 6ea85cad1c..4f3744c5b9 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -4,19 +4,6 @@ would clearly be problematic. Error handling allows us to notice and handle those errors in an explicit fashion, saving the rest of the program from potential issues. -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. -Consider the following example: +For additional information on error handling, see the section on error handling in the [official book][book]. -{error.play} - -This shows that we can induce program failure at will, but raises a -question: what happens if the princess is *not* given a gift? We *could* -explicitly test this with a check against the null string (`""`) as we do -with the snake, but this is not reliable. The problem is that programmers do -not habitually test these checks unless required to by the compiler. - -In order for this to be reliable, we'll want the compiler to point out -cases where there may not be a gift. In this chapter, we will learn to use -`Option` to take care of this condition, as well as various functions to -deal with the results of one or more uses of `Option`. +[book]: https://doc.rust-lang.org/book/error-handling.html \ No newline at end of file diff --git a/examples/error/option/input.md b/examples/error/option/input.md deleted file mode 100644 index 79cd7ad778..0000000000 --- a/examples/error/option/input.md +++ /dev/null @@ -1,21 +0,0 @@ -We determined a snake is an inappropriate gift for a princess. But what if -she expected a gift and didn't receive one? That would be just as bad, so -it needs to be handled! In the `std` library, an `enum` called `Option` -is used when absence is a possibility. It manifests itself as one of -two "options": - -* `Some(T)`: An element of type `T` was found -* `None`: No element was found - -These can either be explicitly handled via `match` or implicitly with -`unwrap`. Implicit handling either returns the inner element or `panic`s. - -Note that it's possible to manually customize `panic` with -[expect][expect], but `unwrap` otherwise leaves us with a less -meaningful output than explicit handling. In the following example, -explicit handling yields a more controlled result while retaining the -option to `panic` if desired. - -{option.play} - -[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md new file mode 100644 index 0000000000..d38dcd322d --- /dev/null +++ b/examples/error/option_unwrap/input.md @@ -0,0 +1,27 @@ +In our previous example, we showed that we can induce program failure at +will. To do so, we simply told our program that a snake is an inappropriate +gift. But what if she expected a gift and didn't receive one? That would be +just as bad, so it needs to be handled! + +We *could* explicitly test this with a check against the null string (`""`) +as we do with the snake, but this is not reliable. Instead, we want the +compiler to point out cases where there may not be a gift. + +In the `std` library, an `enum` called `Option` is used when absence is a +possibility. It manifests itself as one of two "options": + +* `Some(T)`: An element of type `T` was found +* `None`: No element was found + +These can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling either returns the inner element or `panic`s. + +Note that it's possible to manually customize `panic` with +[expect][expect], but `unwrap` otherwise leaves us with a less +meaningful output than explicit handling. In the following example, +explicit handling yields a more controlled result while retaining the +option to `panic` if desired. + +{option_unwrap.play} + +[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option/option.rs b/examples/error/option_unwrap/option_unwrap.rs similarity index 100% rename from examples/error/option/option.rs rename to examples/error/option_unwrap/option_unwrap.rs diff --git a/examples/error/panic/input.md b/examples/error/panic/input.md new file mode 100644 index 0000000000..9703a3c370 --- /dev/null +++ b/examples/error/panic/input.md @@ -0,0 +1,5 @@ +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Here, we explicitly called `panic` on our error condition: + +{panic.play} diff --git a/examples/error/panic_unwrap/panic_unwrap.rs b/examples/error/panic/panic.rs similarity index 100% rename from examples/error/panic_unwrap/panic_unwrap.rs rename to examples/error/panic/panic.rs diff --git a/examples/error/panic_unwrap/input.md b/examples/error/panic_unwrap/input.md deleted file mode 100644 index 0dd1051892..0000000000 --- a/examples/error/panic_unwrap/input.md +++ /dev/null @@ -1,16 +0,0 @@ -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. -Consider the following example: - -{panic_unwrap.play} - -This shows that we can induce program failure at will, but raises a -question: what happens if the princess is *not* given a gift? We *could* -explicitly test this with a check against the null string (`""`) as we do -with the snake, but this is not reliable. The problem is that programmers do -not habitually test these checks unless required to by the compiler. - -In order for this to be reliable, we'll want the compiler to point out -cases where there may not be a gift. In this chapter, we will learn to use -`Option` to take care of this condition, as well as various functions to -deal with the results of one or more uses of `Option`. diff --git a/examples/structure.json b/examples/structure.json index fe80e2b35a..0a96874ace 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,10 +140,11 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "panic_unwrap", "title": "panic & unwrap", "children": null }, - { "id": "option", "title": "Option", "children": null }, - { "id": "map", "title": "map", "children": null }, - { "id": "and_then", "title": "and_then", "children": null }, + { "id": "panic", "title": "panic", "children": null }, + { "id": "option_unwrap", "title": "Option & unwrap", "children": [ + { "id": "map", "title": "Combinators: map", "children": null }, + { "id": "and_then", "title": "Combinators: and_then", "children": null }, + ] }, { "id": "result", "title": "Result", "children": [ { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "aliases for Result", "children": null } @@ -151,10 +152,10 @@ { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, - { "id": "enter_try", "title": "Enter try!", "children": null } + { "id": "enter_try", "title": "try!", "children": null } ] }, { "id": "limits_of_strings", "title": "The limits of strings", "children": null }, - { "id": "reenter_try", "title": "Re-enter try!", "children": null }, + { "id": "reenter_try", "title": "Other uses of try!", "children": null }, { "id": "reenabling_box", "title": "Re-enabling box", "children": null } ] }, { "id": "std", "title": "Std library types", "children": [ From c2466d3c31e81cabb9e8936d36259a51d2832625 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:47:23 -0700 Subject: [PATCH 0485/1122] Removed code from chapter intro Removed panic code example from chapter intro. This information currently exists in `panic`. --- examples/error/error.rs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 examples/error/error.rs diff --git a/examples/error/error.rs b/examples/error/error.rs deleted file mode 100644 index bb69620caa..0000000000 --- a/examples/error/error.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if - // she expresses her disapproval! - if gift == "snake" { panic!("AAAaaaaa!!!!"); } - - println!("I love {}s!!!!!", gift); -} - -fn main() { - give_princess("teddy bear"); - give_princess("snake"); -} From 65cc0304e3dac6b4af6996677b35375eb18a5712 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:50:13 -0700 Subject: [PATCH 0486/1122] Minor grammar fixes --- examples/error/option_unwrap/input.md | 6 +++--- examples/error/panic/input.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md index d38dcd322d..96c19d0900 100644 --- a/examples/error/option_unwrap/input.md +++ b/examples/error/option_unwrap/input.md @@ -1,13 +1,13 @@ In our previous example, we showed that we can induce program failure at will. To do so, we simply told our program that a snake is an inappropriate -gift. But what if she expected a gift and didn't receive one? That would be -just as bad, so it needs to be handled! +gift. But what if the princess expected a gift and didn't receive one? That +would be just as bad, so it needs to be handled! We *could* explicitly test this with a check against the null string (`""`) as we do with the snake, but this is not reliable. Instead, we want the compiler to point out cases where there may not be a gift. -In the `std` library, an `enum` called `Option` is used when absence is a +An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": * `Some(T)`: An element of type `T` was found diff --git a/examples/error/panic/input.md b/examples/error/panic/input.md index 9703a3c370..87c4f544da 100644 --- a/examples/error/panic/input.md +++ b/examples/error/panic/input.md @@ -1,5 +1,5 @@ The simplest error handling mechanism we will see is `panic`. It prints an error message, starts unwinding the task, and usually exits the program. -Here, we explicitly called `panic` on our error condition: +Here, we explicitly call `panic` on our error condition: {panic.play} From 53445eabdb2013e1f4d22492e56778426a458100 Mon Sep 17 00:00:00 2001 From: joemphilips Date: Wed, 29 Jun 2016 22:37:52 +0900 Subject: [PATCH 0487/1122] change section title --- examples/structure.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/structure.json b/examples/structure.json index dbaedc98a0..35f18edecb 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -101,7 +101,7 @@ { "id": "types", "title": "Associated types", "children": null } ] }, { "id": "phantom", "title": "Phantom type parameters", "children": [ - { "id": "testcase_units", "title": "Testcase: unit conversions", "children": null } + { "id": "testcase_units", "title": "Testcase: unit clarification", "children": null } ] } ] }, { "id": "scope", "title": "Scoping rules", "children": [ @@ -146,7 +146,7 @@ { "id": "result", "title": "Result", "children": [ { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "aliases for Result", "children": null } - ] }, + ] }, { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, From 71f48ac99d64270602a55c26bc80d662ade08337 Mon Sep 17 00:00:00 2001 From: "NODA, Kai" Date: Thu, 7 Jul 2016 02:55:33 +0800 Subject: [PATCH 0488/1122] Add examples of nested block comments --- examples/hello/comment/comment.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/hello/comment/comment.rs b/examples/hello/comment/comment.rs index 50e026f9c1..15a4c4d0ad 100644 --- a/examples/hello/comment/comment.rs +++ b/examples/hello/comment/comment.rs @@ -10,7 +10,10 @@ fn main() { /* * This is another type of comment, the block comment. In general, * the line comment is the recommended comment style however the - * block comment is extremely useful for debugging + * block comment is extremely useful for temporarily disabling + * a large chunk of code. /* Block comments can be /* nested, */ */ + * so it takes only a few keystrokes to comment out all the lines + * in this main() function. /*/*/* Try it yourself! */*/*/ */ /* From 213d106ebe2e72e4c82ca5aec711a80211d8bcba Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 7 Jul 2016 18:10:50 -0700 Subject: [PATCH 0489/1122] Minor editing Change wording and shuffling some text around for line length --- examples/error/input.md | 8 ++++---- examples/error/panic/panic.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/error/input.md b/examples/error/input.md index 4f3744c5b9..46175a4393 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -1,9 +1,9 @@ Error handling is the process of handling the possibility of failure. For example, failing to read a file and then continuing to use that *bad* input -would clearly be problematic. Error handling allows us to notice and handle -those errors in an explicit fashion, saving the rest of the program from -potential issues. +would clearly be problematic. Noticing and managing those errors in an +explicit fashion saves the rest of the program from potential issues. -For additional information on error handling, see the section on error handling in the [official book][book]. +For additional information on error handling, see the section on error +handling in the [official book][book]. [book]: https://doc.rust-lang.org/book/error-handling.html \ No newline at end of file diff --git a/examples/error/panic/panic.rs b/examples/error/panic/panic.rs index bb69620caa..26d8f9f94d 100644 --- a/examples/error/panic/panic.rs +++ b/examples/error/panic/panic.rs @@ -1,6 +1,5 @@ fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if - // she expresses her disapproval! + // Princesses hate snakes, so we need to stop if she disapproves! if gift == "snake" { panic!("AAAaaaaa!!!!"); } println!("I love {}s!!!!!", gift); From 6f3be3b2abc28123f36fbcfe53e668b5b37062d9 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 7 Jul 2016 18:13:29 -0700 Subject: [PATCH 0490/1122] Update `option_unwrap`, `map`, and `and_then` Moved `map` and `and_then` into `option_unwrap` to match new chapter layout Condensed text in markdown files Reorganized "See also" sections Simplify some language in code examples --- examples/error/and_then/input.md | 20 -------------- examples/error/map/input.md | 18 ------------- .../{ => option_unwrap}/and_then/and_then.rs | 0 .../error/option_unwrap/and_then/input.md | 21 +++++++++++++++ examples/error/option_unwrap/input.md | 27 +++++++++---------- examples/error/option_unwrap/map/input.md | 22 +++++++++++++++ examples/error/{ => option_unwrap}/map/map.rs | 13 ++++----- examples/error/option_unwrap/option_unwrap.rs | 9 ++++--- 8 files changed, 68 insertions(+), 62 deletions(-) delete mode 100644 examples/error/and_then/input.md delete mode 100644 examples/error/map/input.md rename examples/error/{ => option_unwrap}/and_then/and_then.rs (100%) create mode 100644 examples/error/option_unwrap/and_then/input.md create mode 100644 examples/error/option_unwrap/map/input.md rename examples/error/{ => option_unwrap}/map/map.rs (76%) diff --git a/examples/error/and_then/input.md b/examples/error/and_then/input.md deleted file mode 100644 index f28d828394..0000000000 --- a/examples/error/and_then/input.md +++ /dev/null @@ -1,20 +0,0 @@ -`map()` was described as a chainable way to simplify `match` statements. -However, using `map()` on a function that returns an `Option` results -in the nested `Option>`. Chaining multiple calls together can -then become confusing. - -That's where `and_then()` comes in. Known in some languages as flatmap, `and_then()` calls its function input with the wrapped value or returns `None` if the `Option` is `None`. - -In the following example, `cookable_v2()` results in an `Option`. -Using `map()` instead of `and_then()` would have given an `Option>`, -which is an invalid type for `eat()`. - -{and_then.play} - -### See also: - -[`Option`][option], [`Option::map()`][map], and [`Option::and_then()`][and_then] - -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map -[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/map/input.md b/examples/error/map/input.md deleted file mode 100644 index 7f5fbdc7e5..0000000000 --- a/examples/error/map/input.md +++ /dev/null @@ -1,18 +0,0 @@ -`match` is a valid method for handling `Option`s. However, you may eventually -find heavy usage tedious; this is the case especially with operations that -are only valid with an input. - -For situations where a simplistic mapping of `Some -> Some` and -`None -> None` is needed, `Option` has a built in method called `map()`. - -Multiple `map()` calls can be chained together for even more flexibility. -In the following example, `process()` easily replaces all functions previous -to it while staying compact. - -{map.play} - -### See also: - -[closures][closures] - -[closures]: /fn/closures.html diff --git a/examples/error/and_then/and_then.rs b/examples/error/option_unwrap/and_then/and_then.rs similarity index 100% rename from examples/error/and_then/and_then.rs rename to examples/error/option_unwrap/and_then/and_then.rs diff --git a/examples/error/option_unwrap/and_then/input.md b/examples/error/option_unwrap/and_then/input.md new file mode 100644 index 0000000000..de4fa46344 --- /dev/null +++ b/examples/error/option_unwrap/and_then/input.md @@ -0,0 +1,21 @@ +`map()` was described as a chainable way to simplify `match` statements. +However, using `map()` on a function that returns an `Option` results +in the nested `Option>`. Chaining multiple calls together can +then become confusing. That's where another combinator called `and_then()`, +known in some languages as flatmap, comes in. + +`and_then()` calls its function input with the wrapped value and returns the result. If the `Option` is `None`, then it returns `None` instead. + +In the following example, `cookable_v2()` results in an `Option`. +Using `map()` instead of `and_then()` would have given an +`Option>`, which is an invalid type for `eat()`. + +{and_then.play} + +### See also: + +[closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] + +[closures]: /fn/closures.html +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md index 96c19d0900..e15da58adc 100644 --- a/examples/error/option_unwrap/input.md +++ b/examples/error/option_unwrap/input.md @@ -1,11 +1,11 @@ -In our previous example, we showed that we can induce program failure at -will. To do so, we simply told our program that a snake is an inappropriate -gift. But what if the princess expected a gift and didn't receive one? That -would be just as bad, so it needs to be handled! +In the last example, we showed that we can induce program failure at will. +We told our program to `panic` if the princess received an inappropriate +gift - a snake. But what if the princess expected a gift and didn't receive +one? That case would be just as bad, so it needs to be handled! -We *could* explicitly test this with a check against the null string (`""`) -as we do with the snake, but this is not reliable. Instead, we want the -compiler to point out cases where there may not be a gift. +We *could* test this against the null string (`""`) as we do with a snake. +Since we're using Rust, let's instead have the compiler point out cases +where there's no gift. An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": @@ -13,14 +13,13 @@ possibility. It manifests itself as one of two "options": * `Some(T)`: An element of type `T` was found * `None`: No element was found -These can either be explicitly handled via `match` or implicitly with -`unwrap`. Implicit handling either returns the inner element or `panic`s. +These cases can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling will either return the inner element or `panic`. -Note that it's possible to manually customize `panic` with -[expect][expect], but `unwrap` otherwise leaves us with a less -meaningful output than explicit handling. In the following example, -explicit handling yields a more controlled result while retaining the -option to `panic` if desired. +Note that it's possible to manually customize `panic` with [expect][expect], +but `unwrap` otherwise leaves us with a less meaningful output than explicit +handling. In the following example, explicit handling yields a more +controlled result while retaining the option to `panic` if desired. {option_unwrap.play} diff --git a/examples/error/option_unwrap/map/input.md b/examples/error/option_unwrap/map/input.md new file mode 100644 index 0000000000..31d7f9a1cb --- /dev/null +++ b/examples/error/option_unwrap/map/input.md @@ -0,0 +1,22 @@ +`match` is a valid method for handling `Option`s. However, you may +eventually find heavy usage tedious, especially with operations only valid +with an input. In these cases, [combinators][combinators] can be used to +manage control flow in a modular fashion. + +`Option` has a built in method called `map()`, a combinator for the simple +mapping of `Some -> Some` and `None -> None`. Multiple `map()` calls can be +chained together for even more flexibility. + +In the following example, `process()` replaces all functions previous +to it while staying compact. + +{map.play} + +### See also: + +[closures][closures], [`Option`][option], [`Option::map()`][map] + +[combinators]: https://doc.rust-lang.org/book/glossary.html#combinators +[closures]: /fn/closures.html +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/examples/error/map/map.rs b/examples/error/option_unwrap/map/map.rs similarity index 76% rename from examples/error/map/map.rs rename to examples/error/option_unwrap/map/map.rs index 9c09d72e77..e851bf979a 100644 --- a/examples/error/map/map.rs +++ b/examples/error/option_unwrap/map/map.rs @@ -6,7 +6,7 @@ #[derive(Debug)] struct Chopped(Food); #[derive(Debug)] struct Cooked(Food); -// Peeling food. If there isn't any, then just return `None`. +// Peeling food. If there isn't any, then return `None`. // Otherwise, return the peeled food. fn peel(food: Option) -> Option { match food { @@ -15,7 +15,8 @@ fn peel(food: Option) -> Option { } } -// Like above, we need to know if the peeled food exists before chopping. +// Chopping food. If there isn't any, then return `None`. +// Otherwise, return the chopped food. fn chop(peeled: Option) -> Option { match peeled { Some(Peeled(food)) => Some(Chopped(food)), @@ -23,20 +24,20 @@ fn chop(peeled: Option) -> Option { } } -// Similar to previous checks, but using `map()` instead of `match`. +// Cooking food. Here, we showcase `map()` instead of `match` for case handling. fn cook(chopped: Option) -> Option { chopped.map(|Chopped(food)| Cooked(food)) } -// Alternatively, we can chain multiple uses of `map()` to simplify -// the above process. +// A function to peel, chop, and cook food all in sequence. +// We chain multiple uses of `map()` to simplify the code. fn process(food: Option) -> Option { food.map(|f| Peeled(f)) .map(|Peeled(f)| Chopped(f)) .map(|Chopped(f)| Cooked(f)) } -// It's important to know whether there's food or not before trying to eat it! +// Check whether there's food or not before trying to eat it! fn eat(food: Option) { match food { Some(food) => println!("Mmm. I love {:?}", food), diff --git a/examples/error/option_unwrap/option_unwrap.rs b/examples/error/option_unwrap/option_unwrap.rs index 898728cd46..8ac6ad50fb 100644 --- a/examples/error/option_unwrap/option_unwrap.rs +++ b/examples/error/option_unwrap/option_unwrap.rs @@ -1,5 +1,5 @@ -// The commoner has seen it all, and handles situations well. -// All gifts are handled manually using `match`. +// The commoner has seen it all, and can handle any gift well. +// All gifts are handled explicitly using `match`. fn give_commoner(gift: Option<&str>) { // Specify a course of action for each case. match gift { @@ -10,8 +10,9 @@ fn give_commoner(gift: Option<&str>) { } // Our sheltered princess will `panic` at the sight of snakes. +// All gifts are handled implicitly using `unwrap`. fn give_princess(gift: Option<&str>) { - // Using `unwrap` returns a `panic` when it receives a `None`. + // `unwrap` returns a `panic` when it receives a `None`. let inside = gift.unwrap(); if inside == "snake" { panic!("AAAaaaaa!!!!"); } @@ -19,7 +20,7 @@ fn give_princess(gift: Option<&str>) { } fn main() { - let food = Some("chicken"); + let food = Some("cabbage"); let snake = Some("snake"); let void = None; From f4e7ba62e91426251e01b35498c9195608d2aaa4 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Sat, 9 Jul 2016 00:19:19 -0700 Subject: [PATCH 0491/1122] Updated `Result` Reframed `Result` in the context of `Option` Moved some text from code comment to .md file --- examples/error/result/input.md | 34 ++++++++++++++++++++++----------- examples/error/result/result.rs | 4 +--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/error/result/input.md b/examples/error/result/input.md index b9e03940b9..1dc778ce2f 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -1,22 +1,34 @@ -Previously, we have used the `Option` type to annotate that absence is a possibility. This -absence sometimes appears as an error, such as when `None` is unwrapped. -When multiple failure points may exist, an `Option` can be replaced by the -more general `Result` type. A `Result` has these variants: +[`Result`][result] is a richer version of the [`Option`][option] type that +describes possible *error* instead of possible *absence*. + +That is, `Result` could have one of two outcomes: * `Ok`: An element `T` was found * `Err`: An error was found with element `E` -Similar to `Option`, `Result` also contains the `unwrap()` method which yields the element -`T` or calls `panic!()`. So far, this should seem similar to `Option`: +By convention, the expected outcome is “Ok” while the unexpected outcome is “Err”. -{result.play} +Like `Option`, `Result` has many methods associated with it. `unwrap()`, for +example, either yields the element `T` or `panic`s. For case handling, +there are many combinators between `Result` and `Option` that overlap. -Clearly, panicking on an `Err` leaves an unhelpful error message. Luckily for us, -the upcoming combinators are available to help us with errors. +In working with Rust, you will likely encounter methods that return the +`Result` type, such as the [`parse()`][parse] method. It might not always +be possible to parse a string into the other type, so `parse()` returns a +`Result` indicating possible failure. +Let's see what happens when we successfully and unsuccessfully `parse()` a string: + +{result.play} -### See also: +In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` +to `panic` on. Additionally, the `panic` exits our program and provides an +unpleasant error message. -[`Result`][result] +To improve the quality of our error message, we'll need to be more specific +about the return type. Additionally, we should consider explicitly handling +the error. +[option]: http://doc.rust-lang.org/std/option/enum.Option.html [result]: http://doc.rust-lang.org/std/result/enum.Result.html +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/examples/error/result/result.rs b/examples/error/result/result.rs index 9d98ebfba1..baa9d3faef 100644 --- a/examples/error/result/result.rs +++ b/examples/error/result/result.rs @@ -1,7 +1,5 @@ fn double_number(number_str: &str) -> i32 { - // It might not always be possible to parse a string into the other type, - // so `parse()` returns a `Result` indicating possible failure. Let's - // try using `unwrap()` to get the number out. Will it bite us? + // Let's try using `unwrap()` to get the number out. Will it bite us? 2 * number_str.parse::().unwrap() } From fb02fdabd84ffd32469b195266165789d0b68fef Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 12 Jul 2016 15:55:27 -0400 Subject: [PATCH 0492/1122] Fix example of linking an extern crate This changed long ago, whoops. --- examples/crates/link/input.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/crates/link/input.md b/examples/crates/link/input.md index 7c433811c1..c6ef3d382b 100644 --- a/examples/crates/link/input.md +++ b/examples/crates/link/input.md @@ -6,8 +6,9 @@ modules also apply to libraries. {executable.rs} ``` -# The `-L .` argument adds the current directory to the library search path -$ rustc -L . executable.rs && ./executable +# Where library.rlib is the path to to the compiled library, assumed that it's +# in the same directory here: +$ rustc executable.rs --extern rary=library.rlib && ./executable called rary's `public_function()` called rary's `indirect_access()`, that > called rary's `private_function()` From e5b8ae79068277e2f69fa5a71ada5b05f3e65c62 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 13 Jul 2016 13:48:39 -0700 Subject: [PATCH 0493/1122] Reordering and rewording in Ch8.2, 8.2.2 Based on some comments in #770: The new wording in 8.2 should better introduce closures as they work in Rust. Did some reordering in 8.2.2 to make it less misleading if reader skims the page. Length stayed roughly the same, but hopefully it's clearer in general. --- examples/fn/closures/input.md | 25 ++++++++------ .../fn/closures/input_parameters/input.md | 33 ++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 0242b3cc08..2413eeb327 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -1,13 +1,18 @@ -Closures in Rust, also called lambdas, are functions -that can capture the enclosing environment. Their syntax and capabilities make them -very convenient for on the fly usage. Some characteristics include: +Closures in Rust, also called lambdas, are functions that can capture +the enclosing environment. For example, a closure that captures the x +variable: +```Rust +|val| val + x +``` -* uses `||` instead of `()` around input variables. -* *both* input and return *types* can be inferred. -* input variable *names* must be specified. -* body delimination (`{}`) is optional for a single expression. Mandatory -otherwise. -* the outer environment variables *may* be captured. -* calling a closure is exactly like a function: `call(var)`. +The syntax and capabilities of closures make them very convenient for +on the fly usage. Calling a closure is exactly like calling a function. +However, both input and return types *can* be inferred and input +variable names *must* be specified. + +Other characteristics of closures include: +* using `||` instead of `()` around input variables. +* optional body delimination (`{}`) for a single expression (mandatory otherwise). +* optional capturing of the outer environment variables. {closures.play} diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md index 32e3f43a54..0707285782 100644 --- a/examples/fn/closures/input_parameters/input.md +++ b/examples/fn/closures/input_parameters/input.md @@ -1,23 +1,24 @@ -It has been noted that Rust chooses how to capture variables on the fly -without annotation. This is all very convenient in normal usage however when -writing functions, this ambiguity is not allowed. The closure's complete -type, including which capturing type, must be annotated. The manner of capture -a closure uses is annotated as one of the following `traits`: +While Rust chooses how to capture variables on the fly mostly without +annotation, this ambiguity is not allowed when writing functions. When +taking a closure as an input parameter, Rust will preferentially capture +variables in the least restrictive manner possible on a variable-by-variable +basis. -* `Fn`: takes captures by reference (`&T`) -* `FnMut`: takes captures by mutable reference (`&mut T`) -* `FnOnce`: takes captures by value (`T`) +A closure's complete type must be annotated, including the captured type, as +one of the following `traits`: -Even annotated, these are very flexible: a parameter of `FnOnce` specifies -the closure *may* capture by `T` or `&mut T` or `&T` at will (if a move is -possible, any type of borrow should also be possible). The reverse is not -true: if the parameter is `Fn`, then nothing lower is allowed. Therefore, -the rule is: +* `Fn`: the closure takes capture by reference (`&T`) +* `FnMut`: the closure takes capture by mutable reference (`&mut T`) +* `FnOnce`: the closure takes capture by value (`T`) -* any annotated parameter restricts capture to itself and above +Even annotated, these are very flexible: a parameter of `FnOnce` specifies +the closure *may* capture by `T`, `&mut T`, or `&T` at will. This is because +if a move is possible, then any type of borrow should also be possible. The +reverse is not true: if the parameter is `Fn`, then nothing lower on the +list is allowed. -In addition, Rust will preferentially capture variables in the least -restrictive manner possible on a variable-by-variable basis: +In the following example, try swapping the usage of `Fn`, `FnMut`, and +`FnOnce` to see what happens: {input_parameters.play} From c307ca49c3070f59c904f989d61de42d8967ef98 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 14 Jul 2016 09:54:21 -0700 Subject: [PATCH 0494/1122] Reworded 8.2.2 Updated to hopefully improve clarity --- .../fn/closures/input_parameters/input.md | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md index 0707285782..b85c7f46b3 100644 --- a/examples/fn/closures/input_parameters/input.md +++ b/examples/fn/closures/input_parameters/input.md @@ -1,21 +1,25 @@ -While Rust chooses how to capture variables on the fly mostly without +While Rust chooses how to capture variables on the fly mostly without type annotation, this ambiguity is not allowed when writing functions. When -taking a closure as an input parameter, Rust will preferentially capture -variables in the least restrictive manner possible on a variable-by-variable -basis. - -A closure's complete type must be annotated, including the captured type, as -one of the following `traits`: - -* `Fn`: the closure takes capture by reference (`&T`) -* `FnMut`: the closure takes capture by mutable reference (`&mut T`) -* `FnOnce`: the closure takes capture by value (`T`) - -Even annotated, these are very flexible: a parameter of `FnOnce` specifies -the closure *may* capture by `T`, `&mut T`, or `&T` at will. This is because -if a move is possible, then any type of borrow should also be possible. The -reverse is not true: if the parameter is `Fn`, then nothing lower on the -list is allowed. +taking a closure as an input parameter, the closure's complete type must be +annotated using one of a few `traits`. In order of decreasing restriction, +they are: + +* `Fn`: the closure captures by reference (`&T`) +* `FnMut`: the closure captures by mutable reference (`&mut T`) +* `FnOnce`: the closure captures by value (`T`) + +On a variable-by-variable basis, the compiler will capture variables in the +least restrictive manner possible. + +For instance, consider a parameter annotated as `FnOnce`. This specifies +that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler +will ultimately choose based on how the captured variables are used in the +closure. + +This is because if a move is possible, then any type of borrow should also +be possible. Note that the reverse is not true. If the parameter is +annotated as `Fn`, then capturing variables by `&mut T` or `T` are not +allowed. In the following example, try swapping the usage of `Fn`, `FnMut`, and `FnOnce` to see what happens: From 6f2001ddb26fe6801530b276263b84caa736db1a Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:05:53 -0700 Subject: [PATCH 0495/1122] Minor grammar change to Result Condensed two sentences for readability --- examples/error/result/input.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/error/result/input.md b/examples/error/result/input.md index 1dc778ce2f..13072316b8 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -25,9 +25,8 @@ In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` to `panic` on. Additionally, the `panic` exits our program and provides an unpleasant error message. -To improve the quality of our error message, we'll need to be more specific -about the return type. Additionally, we should consider explicitly handling -the error. +To improve the quality of our error message, we should be more specific +about the return type and consider explicitly handling the error. [option]: http://doc.rust-lang.org/std/option/enum.Option.html [result]: http://doc.rust-lang.org/std/result/enum.Result.html From 876b5ddf20c4c62e61e16e8a353946f6a2bf4fa0 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:31:56 -0700 Subject: [PATCH 0496/1122] Condense 16.6 text and code comments Renamed to "Defining an error type" to improve searching. Updated filenames and structure.json to reflect the change. Reduced wordiness of code comments and block text. --- .../define_error_type.rs} | 25 ++++++++--------- examples/error/define_error_type/input.md | 27 +++++++++++++++++++ examples/error/limits_of_strings/input.md | 27 ------------------- examples/structure.json | 2 +- 4 files changed, 39 insertions(+), 42 deletions(-) rename examples/error/{limits_of_strings/rethink.rs => define_error_type/define_error_type.rs} (56%) create mode 100644 examples/error/define_error_type/input.md delete mode 100644 examples/error/limits_of_strings/input.md diff --git a/examples/error/limits_of_strings/rethink.rs b/examples/error/define_error_type/define_error_type.rs similarity index 56% rename from examples/error/limits_of_strings/rethink.rs rename to examples/error/define_error_type/define_error_type.rs index 868dc69a4f..0802ec377b 100644 --- a/examples/error/limits_of_strings/rethink.rs +++ b/examples/error/define_error_type/define_error_type.rs @@ -4,31 +4,28 @@ use std::fmt; type Result = std::result::Result; #[derive(Debug)] -// Define our error types. These may be customized however is useful for our error -// handling cases. Now we will be able to defer to the underlying tools error -// implementation, write our own errors, or something in between. +// Define our error types. These may be customized for our error handling cases. +// Now we will be able to write our own errors, defer to an underlying error +// implementation, or do something in between. enum DoubleError { // We don't require any extra info to detail this error. EmptyVec, - // We will defer to the parse error implementation for their error. Supplying extra - // info would require adding more data to the type. + // We will defer to the parse error implementation for their error. + // Supplying extra info requires adding more data to the type. Parse(ParseIntError), } -// How the type is displayed is completely separate from where the errors are generated. -// We do not need to be concerned that the display style will clutter the complex logic -// our utility requires. They are separate matters which are handled separately. +// Generation of an error is completely separate from how it is displayed. +// There's no need to be concerned about cluttering complex logic with the display style. // -// We don't store extra info about the errors. If we had desired, for example, to state -// which string failed to parse then we can't without modifying our types to carry that -// information accordingly. +// Note that we don't store any extra info about the errors. This means we can't state +// which string failed to parse without modifying our types to carry that information. impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - // This is a wrapper so defer to the underlying types' own implementation - // of `fmt`. + write!(f, "Please use a vector with at least one element."), + // This is a wrapper, so defer to the underlying types' implementation of `fmt`. DoubleError::Parse(ref e) => e.fmt(f), } } diff --git a/examples/error/define_error_type/input.md b/examples/error/define_error_type/input.md new file mode 100644 index 0000000000..0b51ad74dc --- /dev/null +++ b/examples/error/define_error_type/input.md @@ -0,0 +1,27 @@ +Rust allows us to define our own error types. Up until now, we've been using +`String`s as errors. However, they are somewhat limiting as an error type. + +In general, a "good" error type: + +* Represents different errors with the same type +* Presents nice error messages to the user +* Is easy to compare with other types + - Good: `Err(EmptyVec)` + - Bad: `Err("Please use a vector with at least one element".to_owned())` +* Can hold information about the error + - Good: `Err(BadChar(c, position))` + - Bad: `Err("+ cannot be used here".to_owned())` + +Note that a `String` fulfills the first two criteria, but not the last two. +This makes `String` errors verbose to create and difficult to react to. +It should not be necessary to pollute logic heavy code with `String` formatting simply to display nicely. + +{define_error_type.play} + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/error/limits_of_strings/input.md b/examples/error/limits_of_strings/input.md deleted file mode 100644 index 5bc09e9f51..0000000000 --- a/examples/error/limits_of_strings/input.md +++ /dev/null @@ -1,27 +0,0 @@ -We have been using `Strings` as errors for a while. In fact, this is somewhat limiting as -an error type. Below are the criteria for a good error type. `String` nicely fulfills the first -two but not the second two: - -* Represents different errors with the same type -* Presents nice error messages to the user -* Is easily type comparable. Consider comparing these two types: - - `Err("Please use a vector with at least one element".to_owned())` - - `Err(EmptyVec)` -* Can hold information about the error. Compare: - - `Err("+ cannot be used here".to_owned())` - - `Err(BadChar(c, position))` - -This makes `String` errors both difficult to react to and verbose to create. In fact, a nice -looking error message has nothing to do with how the type is structured. It is simply a -consequence of `Display` being implemented for the type. It should not be necessary to -pollute logic heavy code with `String` formatting simply for nice error messages. - -{rethink.play} - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html -[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/structure.json b/examples/structure.json index 0a96874ace..dc3ad458e9 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -154,7 +154,7 @@ { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, { "id": "enter_try", "title": "try!", "children": null } ] }, - { "id": "limits_of_strings", "title": "The limits of strings", "children": null }, + { "id": "define_error_type", "title": "Defining an error type", "children": null }, { "id": "reenter_try", "title": "Other uses of try!", "children": null }, { "id": "reenabling_box", "title": "Re-enabling box", "children": null } ] }, From bb102f226307e1a3ad7dd2875fa1726554358970 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:54:22 -0700 Subject: [PATCH 0497/1122] Condensed 16.7 text and code comments, minor grammar change to define_error_type.rs reenter_try: Condensed 16.7 text and code comments for better readability and clearer points. Renamed rethink.rs to reenter_try.rs define_error_type.rs: Reverted a text change in the error message --- .../define_error_type/define_error_type.rs | 2 +- examples/error/reenter_try/input.md | 64 ++++++++++--------- .../{rethink.rs => reenter_try.rs} | 6 +- 3 files changed, 39 insertions(+), 33 deletions(-) rename examples/error/reenter_try/{rethink.rs => reenter_try.rs} (92%) diff --git a/examples/error/define_error_type/define_error_type.rs b/examples/error/define_error_type/define_error_type.rs index 0802ec377b..dc04bce925 100644 --- a/examples/error/define_error_type/define_error_type.rs +++ b/examples/error/define_error_type/define_error_type.rs @@ -24,7 +24,7 @@ impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { DoubleError::EmptyVec => - write!(f, "Please use a vector with at least one element."), + write!(f, "please use a vector with at least one element"), // This is a wrapper, so defer to the underlying types' implementation of `fmt`. DoubleError::Parse(ref e) => e.fmt(f), } diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index 0be7b70058..e298ba910d 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -1,38 +1,44 @@ -If you will notice from the previous example, when we call `parse`, the immediate reaction -is to `map` the error from a library error into our new custom error type. +Notice in the previous example that our immediate reaction to calling +`parse` is to `map` the error from a library error into our new custom +error type: ```rust .and_then(|s| s.parse::() .map_err(DoubleError::Parse) ``` -This is a very simple and also common operation so it would be convenient if eliding it -would work but alas, it does not. `and_then` is not sufficiently flexible that it can handle -this; `try!` is though. - -`try!` has previously been explained as either `unwrap` or `return Err(err)` which is only -`93%` correct. It actually means `unwrap` or `return Err(From::from(err))`. Since `From::from` -is a conversion utility between different types, this means if you `try!` something where the -error is convertible to the return type, it will convert automatically. This means, if we -rewrite this example with `try!` when `From::from` is implemented for our error type, -the `map_err` will go away: - -{rethink.play} - -This is actually fairly clean now. If you compare it with the original `panic`, it is very similar -to replacing the `unwrap` calls with `try!` except that the return types are `Result` and so -they must be destructured at the top level. - -However, do not expect error handling of this sort to replace all usage of `unwrap` in -practice. Error handling of this sort tripled our code line count and cannot really be -called simple even if this is heavily biased by the small code size. Indeed, moving a 1000 line -library from `unwrap` to more proper error handling might be feasible in an additional -100 lines of code though the necessary refractoring definitely would not be trivial. - -This is a very reasonable place to be. Many libraries might get away with only -implementing `Display` and then adding `From` on an as needed basis. A serious library -though will have users with certain expections about how it should implement error handling. -In those cases, the error handling will need to be taken one step further. +Since this is a simple and common operation, it would be convenient if it +could be elided. Alas, because `and_then` is not sufficiently flexible, it +cannot. However, we can instead use `try!`. + +`try!` was previously explained as either `unwrap` or `return Err(err)`. +This is only mostly true. It actually means `unwrap` or +`return Err(From::from(err))`. Since `From::from` is a conversion utility +between different types, this means that if you `try!` where the error is +convertible to the return type, it will convert automatically. + +Here, we rewrite the previous example using `try!` As a result, the +`map_err` will go away when `From::from` is implemented for our error type: + +{reenter_try.play} + +This is actually fairly clean now. Compared with the original `panic`, it +is very similar to replacing the `unwrap` calls with `try!` except that the +return types are `Result`. As a result, they must be destructured at the +top level. + +Note that you should not expect error handling of this sort to always +replace `unwrap`. This type of error handling tripled our line count and +cannot really be considered simple (even when heavily biased by the small +code size). + +Indeed, moving a 1000 line library from `unwrap` to more proper error +handling might be feasible in an additional 100 lines of code. However, the +necessary refactoring would most definitely not be trivial. + +Many libraries might get away with only implementing `Display` and +adding `From` on an as needed basis. However, more serious libraries will +eventually need to meet higher expections of error handling implementation. ### See also: diff --git a/examples/error/reenter_try/rethink.rs b/examples/error/reenter_try/reenter_try.rs similarity index 92% rename from examples/error/reenter_try/rethink.rs rename to examples/error/reenter_try/reenter_try.rs index 38533ce91c..da7aaeb9fd 100644 --- a/examples/error/reenter_try/rethink.rs +++ b/examples/error/reenter_try/reenter_try.rs @@ -9,9 +9,9 @@ enum DoubleError { Parse(ParseIntError), } -// Implement the conversion from `ParseIntError` to `DoubleError`. This will be -// automatically called by `try!` if a `ParseIntError` needs converting into -// a `DoubleError`. +// Implement the conversion from `ParseIntError` to `DoubleError`. +// This will be automatically called by `try!` if a `ParseIntError` +// needs to be converted into a `DoubleError`. impl From for DoubleError { fn from(err: ParseIntError) -> DoubleError { DoubleError::Parse(err) From 9b61f950bc2c80ae5861adb79fb793e2aee122a1 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 17:13:58 -0700 Subject: [PATCH 0498/1122] Updated "map for Result" input.md: Reduced wordiness and removed some redundant information that shows up in the previous section. result_map.rs: Renamed from result.rs Minor changes for grammar/readability --- examples/error/result/result_map/input.md | 31 ++++++++----------- .../result_map/{result.rs => result_map.rs} | 5 ++- 2 files changed, 15 insertions(+), 21 deletions(-) rename examples/error/result/result_map/{result.rs => result_map.rs} (82%) diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md index 00641072a5..0c4214ad13 100644 --- a/examples/error/result/result_map/input.md +++ b/examples/error/result/result_map/input.md @@ -1,24 +1,19 @@ -Panicking on `unwrap()` in the previous example gave us an unhelpful error message. -To avoid that, we need to be more specific about the return type. In that example, -recall that the regular element is of type `i32`. To determine the `Err` type, we -look to `parse()`. `parse()` is implemented with the [`FromStr trait`][from_str] -for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. +Panicking in the previous example gave us an unhelpful error message. +To avoid that, we need to be more specific about the return type. There, the +regular element is of type `i32`. -In the example below, note that using the straightforward `match` statement leads to -more cumbersome code. As it turns out, the `map` method we used with `Option` -is also implemented for `Result`. +To determine the `Err` type, we look to +`parse()`, which is implemented with the [`FromStr`][from_str] trait for +[`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. -{result.play} +In the example below, the straightforward `match` statement leads to code +that is overall more cumbersome. Luckily, the `map` method of `Option` is +one of many combinators also implemented for `Result`. [`enum.Result`][result] +contains a complete listing. -Much like `Option`, `Result` implements combinators besides `map`, such as `and_then` -and `unwrap_or`. This even includes those that specifically handle errors, like `map_err`. -[`Result`][result] contains the complete listing. +{result_map.play} -### See also: - -[`i32`][i32], [`FromStr`][from_str], and [`ParseIntErr`][parse_int_error] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html [from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html [i32]: http://doc.rust-lang.org/std/primitive.i32.html +[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html +[result]: http://doc.rust-lang.org/std/result/enum.Result.html diff --git a/examples/error/result/result_map/result.rs b/examples/error/result/result_map/result_map.rs similarity index 82% rename from examples/error/result/result_map/result.rs rename to examples/error/result/result_map/result_map.rs index bb009b24c2..fbf7110bd8 100644 --- a/examples/error/result/result_map/result.rs +++ b/examples/error/result/result_map/result_map.rs @@ -1,7 +1,6 @@ use std::num::ParseIntError; -// With the return type rewritten, we proceed to use pattern matching without -// `unwrap()`, but it is tedious. +// With the return type rewritten, we use pattern matching without `unwrap()`. fn double_number(number_str: &str) -> Result { match number_str.parse::() { Ok(n) => Ok(2 * n), @@ -28,7 +27,7 @@ fn main() { let twenty = double_number("10"); print(twenty); - // The following now provides a much more useful error message + // The following now provides a much more helpful error message. let tt = double_number_map("t"); print(tt); } From 3fec03811a00a852c8ad55ca8c3c49da9d45fc42 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 19:47:28 -0700 Subject: [PATCH 0499/1122] Updated "aliases for Result" alias.rs: Minor grammar change input.md: Condensed and reordered text for readability --- examples/error/result/result_alias/alias.rs | 2 +- examples/error/result/result_alias/input.md | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs index 105f1ebe42..3a948887a4 100644 --- a/examples/error/result/result_alias/alias.rs +++ b/examples/error/result/result_alias/alias.rs @@ -4,7 +4,7 @@ use std::result; // Define a generic alias for a `Result` with the error type `ParseIntError`. type AliasedResult = result::Result; -// Use the alias defined above to refer to our specific `Result` type. +// Use the above alias to refer to our specific `Result` type. fn double_number(number_str: &str) -> AliasedResult { number_str.parse::().map(|n| 2 * n) } diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md index 9d2e67c311..5085e5dc80 100644 --- a/examples/error/result/result_alias/input.md +++ b/examples/error/result/result_alias/input.md @@ -1,13 +1,14 @@ How about when we want to reuse a specific `Result` type many times? -It quickly becomes tedious to write out the full type name, but recall that Rust allows -us to create [aliases][typealias]. A generic alias may conveniently be defined for the -specific `Result` in question: - -{alias.play} +Recall that Rust allows us to create [aliases][typealias]. Conveniently, +we can define one for the specific `Result` in question. At a module level, creating aliases can be particularly helpful. Errors -found in a specific module often have the same `Err` type, so a single alias can succinctly -define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! +found in a specific module often have the same `Err` type, so a single alias +can succinctly define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! + +Here's a quick example to show off the syntax: + +{alias.play} ### See also: From 7ddda5f4ee6a6c7faf08e893d332414385a6e740 Mon Sep 17 00:00:00 2001 From: ubsan Date: Tue, 26 Jul 2016 17:02:02 -0700 Subject: [PATCH 0500/1122] Fix Options with Results up a little fixes #777 --- .../error/option_with_result/option_result.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/error/option_with_result/option_result.rs b/examples/error/option_with_result/option_result.rs index 5d13f054c1..42d5d529f8 100644 --- a/examples/error/option_with_result/option_result.rs +++ b/examples/error/option_with_result/option_result.rs @@ -1,23 +1,23 @@ -// Our first attempt uses `unwrap` and provides unhelpful errors. +// Our first attempt uses `unwrap` and unhelpfully panics. fn double_first(vec: Vec<&str>) -> i32 { - // Returns an error if the input vector is empty: + // Panics if the input vector is empty: let first = vec.first().unwrap(); - // Returns an error if the element doesn't parse to a number: + // Panics if the element doesn't parse to a number: 2 * first.parse::().unwrap() } fn main() { let numbers = vec!["93", "18"]; + let strings = vec!["tofu", "cheese", "bell pepper"]; let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; println!("The first doubled is {}", double_first(numbers)); - - // This line results in the first error: - println!("The first doubled is {}", double_first(empty)); - // ^ Comment this out to see the second error. - - // This line results in a second error: + + // This line results in the first panic: println!("The first doubled is {}", double_first(strings)); + // ^ Comment this out to see the second panic. + + // This line results in a second panic: + println!("The first doubled is {}", double_first(empty)); } From fd86f8d7f14fce25c75afae2bc3cf98c619e4881 Mon Sep 17 00:00:00 2001 From: ubsan Date: Tue, 26 Jul 2016 17:29:33 -0700 Subject: [PATCH 0501/1122] 5.3: trivial_numeric_casts is now allowed by default Fix #729 --- examples/cast/alias/alias.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/cast/alias/alias.rs b/examples/cast/alias/alias.rs index 42fa99b080..74e6f52938 100644 --- a/examples/cast/alias/alias.rs +++ b/examples/cast/alias/alias.rs @@ -7,8 +7,6 @@ type Inch = u64; type u64_t = u64; // TODO ^ Try removing the attribute -// Use an attribute to silence warnings -#[allow(trivial_numeric_casts)] fn main() { // `NanoSecond` = `Inch` = `u64_t` = `u64`. let nanoseconds: NanoSecond = 5 as u64_t; From 63f55a3286af5e3bbe08a4111e10c406ec6d5ed9 Mon Sep 17 00:00:00 2001 From: ubsan Date: Tue, 26 Jul 2016 17:59:35 -0700 Subject: [PATCH 0502/1122] Fix up process examples Fix #736 --- examples/std_misc/process/input.md | 4 ++-- examples/std_misc/process/wait/input.md | 4 ++-- examples/std_misc/process/wait/wait.rs | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/std_misc/process/input.md b/examples/std_misc/process/input.md index 820d906fd0..06c2ce6ec2 100644 --- a/examples/std_misc/process/input.md +++ b/examples/std_misc/process/input.md @@ -1,5 +1,5 @@ -The `ProcessOutput` struct represents the output of a finished child process, -and the `Command` struct is a process builder. +The `process::Output` struct represents the output of a finished child process, +and the `process::Command` struct is a process builder. {process.play} diff --git a/examples/std_misc/process/wait/input.md b/examples/std_misc/process/wait/input.md index cdf87be219..33076ab95b 100644 --- a/examples/std_misc/process/wait/input.md +++ b/examples/std_misc/process/wait/input.md @@ -1,5 +1,5 @@ -When a `Process` goes out of scope, its `drop` method will *wait* until the -child process finishes before releasing the resource. +If you'd like to wait for a `process::Child` to finish, you must call +`Child::wait`, which will return a `process::ExitStatus`. {wait.rs} diff --git a/examples/std_misc/process/wait/wait.rs b/examples/std_misc/process/wait/wait.rs index 37cbf9276e..836908b328 100644 --- a/examples/std_misc/process/wait/wait.rs +++ b/examples/std_misc/process/wait/wait.rs @@ -1,7 +1,8 @@ use std::process::Command; fn main() { - let _process = Command::new("sleep").arg("5").spawn(); + let child = Command::new("sleep").arg("5").spawn().unwrap(); + let _result = child.wait().unwrap(); println!("reached end of main"); } From 169cc968053777764b99daea5d3310ca0b25fb53 Mon Sep 17 00:00:00 2001 From: ubsan Date: Tue, 26 Jul 2016 18:04:22 -0700 Subject: [PATCH 0503/1122] Fix mutability issues --- examples/std_misc/process/wait/wait.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/process/wait/wait.rs b/examples/std_misc/process/wait/wait.rs index 836908b328..c5010652df 100644 --- a/examples/std_misc/process/wait/wait.rs +++ b/examples/std_misc/process/wait/wait.rs @@ -1,7 +1,7 @@ use std::process::Command; fn main() { - let child = Command::new("sleep").arg("5").spawn().unwrap(); + let mut child = Command::new("sleep").arg("5").spawn().unwrap(); let _result = child.wait().unwrap(); println!("reached end of main"); From e56e3550450e2c2d9595f6c34488e6d11a5428bd Mon Sep 17 00:00:00 2001 From: Jonathan L Date: Wed, 27 Jul 2016 12:07:16 -0700 Subject: [PATCH 0504/1122] Update input.md Reworded third characteristic optional -> ability --- examples/fn/closures/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 2413eeb327..3ba6cd22a7 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -13,6 +13,6 @@ variable names *must* be specified. Other characteristics of closures include: * using `||` instead of `()` around input variables. * optional body delimination (`{}`) for a single expression (mandatory otherwise). -* optional capturing of the outer environment variables. +* the ability to capture the outer environment variables. {closures.play} From b4bb7ed8b0cedbfa154d4cdfff575a00919e6752 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:00:24 -0700 Subject: [PATCH 0505/1122] Renamed 16.5, combined content mostly with 16.5.1 Renamed 16.5 for better searching: Options with Results -> Multiple error types Updated structure.json, option_result.rs to match input.md: Reduced wordiness of explanations Reworked code example to a snippet New code example reflects the example of old 16.5.1 --Reasoning: no longer requires flipping between pages to see the difference when replacing .unwrap with explicit error handling Added See also for ok_or and map_err, as they are used in the new code example, but not explicitly defined in the text --- examples/error/option_with_result/input.md | 49 ++++++++++++++----- .../multiple_error_types.rs | 30 ++++++++++++ .../error/option_with_result/option_result.rs | 23 --------- examples/structure.json | 2 +- 4 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 examples/error/option_with_result/multiple_error_types.rs delete mode 100644 examples/error/option_with_result/option_result.rs diff --git a/examples/error/option_with_result/input.md b/examples/error/option_with_result/input.md index e1112363b8..9201d57429 100644 --- a/examples/error/option_with_result/input.md +++ b/examples/error/option_with_result/input.md @@ -1,16 +1,41 @@ -In the following sections, we will see how to combine separate operations returning -`Option` and `Result` into a single operation that returns whichever one makes the -most sense. +The previous examples have always been very convenient; `Result`s interact +with other `Result`s and `Option`s interact with other `Option`s. -The previous examples have always been very convenient; a `Result` interacted -with another `Result` and an `Option` interacted with another `Option`. Unfortunately, -it's not always that easy. An `Option` may have to interact with a `Result`, and a -`Result` may have to interact with a `Result`. +Sometimes an `Option` needs to interact with a `Result`, or a `Result` +needs to interact with a `Result`. In those cases, we want to +handle the *composition of distinct error types*. -To start us off, the example below uses `Vec::first` and `parse::` with `unwrap` to -generate errors. `Vec::first` returns an `Option`, while `parse::` -returns a `Result`. +In the following code, two instances of `unwrap` generate different error +types. `Vec::first` returns an `Option`, while `parse::` returns a +`Result`: -Note that this code "works", but is meant to showcase **improper** error handling: +```rust +fn double_first(vec: Vec<&str>) -> i32 { + let first = vec.first().unwrap(); // Generate error 1 + 2 * first.parse::().unwrap() // Generate error 2 +} -{option_result.play} +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {}", double_first(empty)); + // Error 1: the input vector is empty + + println!("The first doubled is {}", double_first(strings)); + // Error 2: the element doesn't parse to a number +} +``` + +Using our knowledge of combinators, we can rewrite the above to explicitly +handle errors. In doing so, we convert both `Option`s and `Result`s into +`Result`s, and map them to the same error type (`String`): + +{multiple_error_types.play} + +### See Also: + +[`Option::ok_or`][okor], [Result::map_err][maperr] + +[okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or +[maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err diff --git a/examples/error/option_with_result/multiple_error_types.rs b/examples/error/option_with_result/multiple_error_types.rs new file mode 100644 index 0000000000..2a5d0a679c --- /dev/null +++ b/examples/error/option_with_result/multiple_error_types.rs @@ -0,0 +1,30 @@ +// Use `String` as our error type +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + .ok_or("Please use a vector with at least one element.".to_owned()) + .and_then(|s| s.parse::() + // Map the errors `parse` yields to `String`. + .map_err(|e| e.to_string()) + // `Result` is the new return type, + // and we can now double the number inside. + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(empty)); + print(double_first(strings)); +} \ No newline at end of file diff --git a/examples/error/option_with_result/option_result.rs b/examples/error/option_with_result/option_result.rs deleted file mode 100644 index 5d13f054c1..0000000000 --- a/examples/error/option_with_result/option_result.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Our first attempt uses `unwrap` and provides unhelpful errors. -fn double_first(vec: Vec<&str>) -> i32 { - // Returns an error if the input vector is empty: - let first = vec.first().unwrap(); - - // Returns an error if the element doesn't parse to a number: - 2 * first.parse::().unwrap() -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - println!("The first doubled is {}", double_first(numbers)); - - // This line results in the first error: - println!("The first doubled is {}", double_first(empty)); - // ^ Comment this out to see the second error. - - // This line results in a second error: - println!("The first doubled is {}", double_first(strings)); -} diff --git a/examples/structure.json b/examples/structure.json index dc3ad458e9..25ddf335a0 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -149,7 +149,7 @@ { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "aliases for Result", "children": null } ] }, - { "id": "option_with_result", "title": "Options with Results", "children": [ + { "id": "multiple_error_types", "title": "Multiple error types", "children": [ { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, { "id": "enter_try", "title": "try!", "children": null } From c7465e54ed6a56c32c5dbcc1d6314cf1da88e4ce Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:01:38 -0700 Subject: [PATCH 0506/1122] Renamed rethink.rs to reenabling_box.rs Renamed to match structure.json --- examples/error/reenabling_box/input.md | 2 +- examples/error/reenabling_box/{rethink.rs => reenabling_box.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename examples/error/reenabling_box/{rethink.rs => reenabling_box.rs} (100%) diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md index ed826e6c43..78073af443 100644 --- a/examples/error/reenabling_box/input.md +++ b/examples/error/reenabling_box/input.md @@ -32,7 +32,7 @@ trait Error: Debug + Display { By implementing this, our previous example would be just as valid when the error type is `Box` as it was before with `DoubleError`. -{rethink.play} +{reenabling_box.play} ### See also: diff --git a/examples/error/reenabling_box/rethink.rs b/examples/error/reenabling_box/reenabling_box.rs similarity index 100% rename from examples/error/reenabling_box/rethink.rs rename to examples/error/reenabling_box/reenabling_box.rs From e9c3b93e9d3a7305e42565e62833453c2ecec478 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:02:42 -0700 Subject: [PATCH 0507/1122] Renamed folder for 16.5 option_with_result -> multiple_error_types Now matches structure.json --- .../combinator_combinations/input.md | 0 .../combinator_combinations/result_try.rs | 0 .../enter_try/input.md | 0 .../{option_with_result => multiple_error_types}/enter_try/try.rs | 0 .../error/{option_with_result => multiple_error_types}/input.md | 0 .../multiple_error_types.rs | 0 .../result_string_errors/input.md | 0 .../result_string_errors/result_string.rs | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename examples/error/{option_with_result => multiple_error_types}/combinator_combinations/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/combinator_combinations/result_try.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/enter_try/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/enter_try/try.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/multiple_error_types.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/result_string_errors/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/result_string_errors/result_string.rs (100%) diff --git a/examples/error/option_with_result/combinator_combinations/input.md b/examples/error/multiple_error_types/combinator_combinations/input.md similarity index 100% rename from examples/error/option_with_result/combinator_combinations/input.md rename to examples/error/multiple_error_types/combinator_combinations/input.md diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/multiple_error_types/combinator_combinations/result_try.rs similarity index 100% rename from examples/error/option_with_result/combinator_combinations/result_try.rs rename to examples/error/multiple_error_types/combinator_combinations/result_try.rs diff --git a/examples/error/option_with_result/enter_try/input.md b/examples/error/multiple_error_types/enter_try/input.md similarity index 100% rename from examples/error/option_with_result/enter_try/input.md rename to examples/error/multiple_error_types/enter_try/input.md diff --git a/examples/error/option_with_result/enter_try/try.rs b/examples/error/multiple_error_types/enter_try/try.rs similarity index 100% rename from examples/error/option_with_result/enter_try/try.rs rename to examples/error/multiple_error_types/enter_try/try.rs diff --git a/examples/error/option_with_result/input.md b/examples/error/multiple_error_types/input.md similarity index 100% rename from examples/error/option_with_result/input.md rename to examples/error/multiple_error_types/input.md diff --git a/examples/error/option_with_result/multiple_error_types.rs b/examples/error/multiple_error_types/multiple_error_types.rs similarity index 100% rename from examples/error/option_with_result/multiple_error_types.rs rename to examples/error/multiple_error_types/multiple_error_types.rs diff --git a/examples/error/option_with_result/result_string_errors/input.md b/examples/error/multiple_error_types/result_string_errors/input.md similarity index 100% rename from examples/error/option_with_result/result_string_errors/input.md rename to examples/error/multiple_error_types/result_string_errors/input.md diff --git a/examples/error/option_with_result/result_string_errors/result_string.rs b/examples/error/multiple_error_types/result_string_errors/result_string.rs similarity index 100% rename from examples/error/option_with_result/result_string_errors/result_string.rs rename to examples/error/multiple_error_types/result_string_errors/result_string.rs From c7db1a37f799a1c8a8f5a103a231acabca083259 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 17:58:40 -0700 Subject: [PATCH 0508/1122] Updated multiple_error_types (input.md) Rewording for better transitions --- examples/error/multiple_error_types/input.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/error/multiple_error_types/input.md b/examples/error/multiple_error_types/input.md index 9201d57429..872c4220b8 100644 --- a/examples/error/multiple_error_types/input.md +++ b/examples/error/multiple_error_types/input.md @@ -1,9 +1,10 @@ The previous examples have always been very convenient; `Result`s interact with other `Result`s and `Option`s interact with other `Option`s. -Sometimes an `Option` needs to interact with a `Result`, or a `Result` -needs to interact with a `Result`. In those cases, we want to -handle the *composition of distinct error types*. +Sometimes an `Option` needs to interact with a `Result`, or a +`Result` needs to interact with a `Result`. In those +cases, we want to manage our different error types in a way that makes them +composable and easy to interact with. In the following code, two instances of `unwrap` generate different error types. `Vec::first` returns an `Option`, while `parse::` returns a @@ -27,12 +28,17 @@ fn main() { } ``` -Using our knowledge of combinators, we can rewrite the above to explicitly -handle errors. In doing so, we convert both `Option`s and `Result`s into -`Result`s, and map them to the same error type (`String`): +Using our knowledge of combinators, we can rewrite the above to explicitly +handle errors. Since two different types of errors can occur, we need to +convert them to a common type such as a `String`. + +To do so, we convert both the `Option` and `Result` into `Result`s, and +then map their errors to the same type: {multiple_error_types.play} +In the next section, we'll see an alternate method of explicitly handling these errors. + ### See Also: [`Option::ok_or`][okor], [Result::map_err][maperr] From a6d1eeaf69a45abd4449c21819698bb707945eb9 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 18:01:22 -0700 Subject: [PATCH 0509/1122] Removed "Strings as errors" chapter, Renamed result_try to early_returns Updated structure.json to reflect removal/renaming +Very minor change to multiple_error_types.rs --- .../result_try.rs => early_returns/early_returns.rs} | 0 .../{combinator_combinations => early_returns}/input.md | 0 examples/error/multiple_error_types/multiple_error_types.rs | 2 +- examples/structure.json | 3 +-- 4 files changed, 2 insertions(+), 3 deletions(-) rename examples/error/multiple_error_types/{combinator_combinations/result_try.rs => early_returns/early_returns.rs} (100%) rename examples/error/multiple_error_types/{combinator_combinations => early_returns}/input.md (100%) diff --git a/examples/error/multiple_error_types/combinator_combinations/result_try.rs b/examples/error/multiple_error_types/early_returns/early_returns.rs similarity index 100% rename from examples/error/multiple_error_types/combinator_combinations/result_try.rs rename to examples/error/multiple_error_types/early_returns/early_returns.rs diff --git a/examples/error/multiple_error_types/combinator_combinations/input.md b/examples/error/multiple_error_types/early_returns/input.md similarity index 100% rename from examples/error/multiple_error_types/combinator_combinations/input.md rename to examples/error/multiple_error_types/early_returns/input.md diff --git a/examples/error/multiple_error_types/multiple_error_types.rs b/examples/error/multiple_error_types/multiple_error_types.rs index 2a5d0a679c..bcc909a069 100644 --- a/examples/error/multiple_error_types/multiple_error_types.rs +++ b/examples/error/multiple_error_types/multiple_error_types.rs @@ -7,7 +7,7 @@ fn double_first(vec: Vec<&str>) -> Result { // Otherwise, provide an `Err` containing this `String`. .ok_or("Please use a vector with at least one element.".to_owned()) .and_then(|s| s.parse::() - // Map the errors `parse` yields to `String`. + // Map any errors that `parse` yields to `String`. .map_err(|e| e.to_string()) // `Result` is the new return type, // and we can now double the number inside. diff --git a/examples/structure.json b/examples/structure.json index 25ddf335a0..8580133f2f 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -150,8 +150,7 @@ { "id": "result_alias", "title": "aliases for Result", "children": null } ] }, { "id": "multiple_error_types", "title": "Multiple error types", "children": [ - { "id": "result_string_errors", "title": "Strings as errors", "children": null }, - { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, + { "id": "early_returns", "title": "Early returns", "children": null }, { "id": "enter_try", "title": "try!", "children": null } ] }, { "id": "define_error_type", "title": "Defining an error type", "children": null }, From 54500528351853f14ac7df5fd7064c303197f6b4 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 18:21:20 -0700 Subject: [PATCH 0510/1122] Update input.md (early_returns) New text in its entirety, with inspiration from https://doc.rust-lang.org/book/error-handling.html#early-returns The .rs file will include a rewritten version of the "Multiple error types" example. --- .../early_returns/input.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/input.md b/examples/error/multiple_error_types/early_returns/input.md index b7d1cb76c0..bb61a12182 100644 --- a/examples/error/multiple_error_types/early_returns/input.md +++ b/examples/error/multiple_error_types/early_returns/input.md @@ -1,15 +1,15 @@ -What if multiple `Results` needed to interact together? Is it still reasonably convenient? -It turns out, not really. +In the previous example, we explicitly handled the errors using combinators. +Another way to deal with this case analysis is to use a combination of +`match` statements and *early returns*. -{result_try.play} +That is, we can simply stop executing the function and return the error if +one occurs. For some, this form of code can be easier to both read and +write. Consider this version of the previous example, rewritten using early returns: -What is happening is this approach tries to work with the data without ever removing the `Ok` -wrapper on it. Sometimes it is a good approach but in this case it is really awkward. What if -we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. +{early_returns.play} -### See also: +At this point, we've learned to explicitly handle errors using combinators +and early returns. While we generally want to avoid panicking, always +handling errors explicitly is cumbersome. -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +So what if we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. From 8835814e9b89e94cee85d07b9ed4b26769cab423 Mon Sep 17 00:00:00 2001 From: ubsan Date: Sun, 7 Aug 2016 12:31:58 -0700 Subject: [PATCH 0511/1122] Switch from f64 to f32 Allows the activity to work without casting stylistic choice - could also change the activity to take f64. Unknown which is better. --- examples/custom_types/structs/structs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/custom_types/structs/structs.rs b/examples/custom_types/structs/structs.rs index 84178fc7ef..525fd27d3d 100644 --- a/examples/custom_types/structs/structs.rs +++ b/examples/custom_types/structs/structs.rs @@ -2,12 +2,12 @@ struct Nil; // A tuple struct -struct Pair(i32, f64); +struct Pair(i32, f32); // A struct with two fields struct Point { - x: f64, - y: f64, + x: f32, + y: f32, } // Structs can be reused as fields of another struct From 76a4dd6e52e7dea68f2a18033d447640e800fec4 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 8 Aug 2016 23:56:41 -0400 Subject: [PATCH 0512/1122] trait/clone: fix typo in comment --- examples/trait/clone/clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/clone/clone.rs b/examples/trait/clone/clone.rs index 70b67ea740..2cad5db2b0 100644 --- a/examples/trait/clone/clone.rs +++ b/examples/trait/clone/clone.rs @@ -24,7 +24,7 @@ fn main() { let moved_pair = pair; println!("copy: {:?}", moved_pair); - // Error! `pair` has lost it resources + // Error! `pair` has lost its resources //println!("original: {:?}", pair); // TODO ^ Try uncommenting this line From 758f69c6b8fb3bf69a3d1bab500bfa15b174fb9b Mon Sep 17 00:00:00 2001 From: Shubham Jain Date: Wed, 17 Aug 2016 22:29:09 +0530 Subject: [PATCH 0513/1122] removed derive attribute, to avoid confusion --- .../flow_control/match/destructuring/destructure_enum/enum.rs | 2 -- .../match/destructuring/destructure_enum/input.md | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs index c917840440..4e252adf7c 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/enum.rs +++ b/examples/flow_control/match/destructuring/destructure_enum/enum.rs @@ -1,8 +1,6 @@ -// Must derive `Debug` so `println!` can be used. // `allow` required to silence warnings because only // one variant is used. #[allow(dead_code)] -#[derive(Debug)] enum Color { // These 3 are specified solely by their name. Red, diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index 9f6a352ed9..e532afca20 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -4,10 +4,8 @@ An `enum` is destructured similarly: ### See also: -[`#[allow(...)]`][allow], [color models][color_models], [`enum`][enum], -and [`#[derive(...)]`][derive] +[`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] [allow]: /attribute/unused.html [color_models]: http://en.wikipedia.org/wiki/Color_model -[derive]: /trait/derive.html [enum]: /custom_types/enum.html From 10fa2becaecdd837a6e21d20362414d8a7e84420 Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (Havvy)" Date: Fri, 19 Aug 2016 09:30:48 +0000 Subject: [PATCH 0514/1122] Use structs, not tuples, for generics impl example. Over IRC, had a user say they found the usage of tuple get syntax to be confusing (`self.0`) so this patch replaces the usage of that with more mundane syntax so that learners can focus on the impl syntax. --- examples/generics/impl/impl.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/generics/impl/impl.rs b/examples/generics/impl/impl.rs index 5587246380..85f5d9134e 100644 --- a/examples/generics/impl/impl.rs +++ b/examples/generics/impl/impl.rs @@ -1,19 +1,24 @@ -struct Val (f64,); -struct GenVal(T,); +struct Val { + val: f64 +} + +struct GenVal{ + gen_val: T +} // impl of Val impl Val { - fn value(&self) -> &f64 { &self.0 } + fn value(&self) -> &f64 { &self.val } } // impl of GenVal for a generic type `T` impl GenVal { - fn value(&self) -> &T { &self.0 } + fn value(&self) -> &T { &self.gen_val } } fn main() { - let x = Val(3.0); - let y = GenVal(3i32); + let x = Val { val: 3.0 }; + let y = GenVal { gen_val: 3i32 }; println!("{}, {}", x.value(), y.value()); } From f5b314c799d538fa0f91b5f0bc528b4409afad7e Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (Havvy)" Date: Fri, 19 Aug 2016 09:37:34 +0000 Subject: [PATCH 0515/1122] Add access of tuple struct fields in structs example. This is where I would expect to find an example on this part of the syntax, ergo upon not finding it, I decided to add it. --- examples/custom_types/structs/structs.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/custom_types/structs/structs.rs b/examples/custom_types/structs/structs.rs index 525fd27d3d..d8c538f439 100644 --- a/examples/custom_types/structs/structs.rs +++ b/examples/custom_types/structs/structs.rs @@ -39,6 +39,9 @@ fn main() { // Instantiate a tuple struct let pair = Pair(1, 0.1); + // Access the fields of a tuple struct + println!("pair contains {:?} and {:?}", pair.0, pair.1); + // Destructure a tuple struct let Pair(integer, decimal) = pair; From 218def6b257c41a39ead980efd7af289451692d4 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 21 Aug 2016 12:58:12 +0200 Subject: [PATCH 0516/1122] unsafe: cast::transmute is now called mem::transmute --- examples/unsafe/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index a1f0807ab1..a0f85eecf1 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -8,7 +8,7 @@ used for: * dereferencing raw pointers * calling a function over FFI (but this is covered in a different part of the book) -* changing types through `std::cast::transmute` +* changing types through `std::mem::transmute` * inline assembly ### Raw Pointers From 701ddbd806b7d2b114eb8b43164323fe09b81085 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 30 Aug 2016 21:03:33 -0400 Subject: [PATCH 0517/1122] fn/methods: Clarify method comparison to static call with reference. --- examples/fn/methods/methods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/methods/methods.rs b/examples/fn/methods/methods.rs index 91efad1782..ca45c7a9be 100644 --- a/examples/fn/methods/methods.rs +++ b/examples/fn/methods/methods.rs @@ -80,7 +80,7 @@ fn main() { // Instance methods are called using the dot operator // Note that the first argument `&self` is implicitly passed, i.e. - // `rectangle.perimeter()` === `perimeter(&rectangle)` + // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)` println!("Rectangle perimeter: {}", rectangle.perimeter()); println!("Rectangle area: {}", rectangle.area()); From 4a4c23f55bb68b97a66ce4d54a426cc38a67bfd5 Mon Sep 17 00:00:00 2001 From: Aashish Welling Date: Tue, 6 Sep 2016 22:48:03 -0400 Subject: [PATCH 0518/1122] Added missing backtick --- examples/scope/lifetime/fn/fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index be1f084fdf..5aafc4c942 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -21,7 +21,7 @@ fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } //fn invalid_output<'a>() -> &'a i32 { &7 } -// The above is invalid: 'a` must live longer than the function. +// The above is invalid: `'a` must live longer than the function. // Here, `&7` would create an `i32`, followed by a reference. // Then the data is dropped upon exiting the scope, leaving // a reference to invalid data to be returned. From 9c2b7709fc2207868cc14107e045259b30d0c658 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 15:05:38 -0700 Subject: [PATCH 0519/1122] Minor rewording in `early_returns` --- examples/error/multiple_error_types/early_returns/input.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/input.md b/examples/error/multiple_error_types/early_returns/input.md index bb61a12182..61f94e3c7f 100644 --- a/examples/error/multiple_error_types/early_returns/input.md +++ b/examples/error/multiple_error_types/early_returns/input.md @@ -9,7 +9,8 @@ write. Consider this version of the previous example, rewritten using early retu {early_returns.play} At this point, we've learned to explicitly handle errors using combinators -and early returns. While we generally want to avoid panicking, always -handling errors explicitly is cumbersome. +and early returns. While we generally want to avoid panicking, explicitly +handling all of our errors is cumbersome. -So what if we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. +In the next section, we'll introduce `try!` for the cases where we simply +need to `unwrap` without possibly inducing `panic`. From 12ec0b2a9d305e30eb25d7bd3c85cc07fc7ebb9a Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:25:00 -0700 Subject: [PATCH 0520/1122] Rename reenabling_box and added `` to some other sections Renamed reenabling_box to `Box`ing errors Added `` to other chapter sections for consistency. Added `` to `Box`ing errors section for consistency. --- .../boxing_errors.rs} | 0 examples/error/boxing_errors/input.md | 43 +++++++++++++++++++ examples/error/reenabling_box/input.md | 42 ------------------ examples/structure.json | 20 ++++----- 4 files changed, 53 insertions(+), 52 deletions(-) rename examples/error/{reenabling_box/reenabling_box.rs => boxing_errors/boxing_errors.rs} (100%) create mode 100644 examples/error/boxing_errors/input.md delete mode 100644 examples/error/reenabling_box/input.md diff --git a/examples/error/reenabling_box/reenabling_box.rs b/examples/error/boxing_errors/boxing_errors.rs similarity index 100% rename from examples/error/reenabling_box/reenabling_box.rs rename to examples/error/boxing_errors/boxing_errors.rs diff --git a/examples/error/boxing_errors/input.md b/examples/error/boxing_errors/input.md new file mode 100644 index 0000000000..d8136f25ad --- /dev/null +++ b/examples/error/boxing_errors/input.md @@ -0,0 +1,43 @@ +By implementing `Display` and `From` for our error type, we enabled +almost all of the `std` library error handling tools. However, we missed +something: the ability to easily `Box` our error type. + +The `std` library automatically converts any type that implements the +`Error` trait into the trait object `Box`, via `From`. To a +library user, this conveniently allows the following: + +```rust +fn foo(...) -> Result> { ... } +``` + +A user may use any variety of external libraries which each provide their own error +types. In order to define a valid `Result` type, the user has a few choices: + +* define a new wrapper error type around the library's error types +* convert the error types to `String` or another intermediate choice +* `Box` the error types into `Box` via type erasure + +"Boxing" the error type is a common choice. The drawback is that the +underlying error type is only known at runtime and not +[statically determined][dynamic_dispatch]. As mentioned above, all that +needs to be done is to implement the `Error` trait: + +```rust +trait Error: Debug + Display { + fn description(&self) -> &str; + fn cause(&self) -> Option<&Error>; +} +``` + +With this implementation, let's look at our most recent example. Note that +it is just as valid with the error type of `Box` as it was before +with `DoubleError`: + +{boxing_errors.play} + +### See also: + +[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] + +[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch +[error]: http://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md deleted file mode 100644 index 78073af443..0000000000 --- a/examples/error/reenabling_box/input.md +++ /dev/null @@ -1,42 +0,0 @@ -We have seen that by implementing `Display` and `From` for our error type, we have enabled -usage of almost all of the std library error handling tools. That is, we missed one -capability: the ability to easily `box` our error type. - -Namely, the std library will automatically convert from any type which implements the -`Error` trait into the trait object `Box` via `From`. To a library user, this -conveniently allows the following: - -```rust -// Any error type automatically convertible to `Box` may be used here. -fn foo(...) -> Result> { ... } -``` - -For example, a user may use a variety of libraries which each provide their own error -types. In order to define a valid `Result` type, the user has a few choices: - -* define a new wrapper error type around the external libraries error types -* convert it to `String` or some other intermediate choice -* box it up into `Box` via type erasure - -Boxing it is a common choice. The only penalty is that the underlying error type is only known -at runtime and not [statically determined][dynamic_dispatch]. All that needs to be done to enable -this is implement the `Error` trait: - -```rust -trait Error: Debug + Display { - fn description(&self) -> &str; - fn cause(&self) -> Option<&Error>; -} -``` - -By implementing this, our previous example would be just as valid when the error type -is `Box` as it was before with `DoubleError`. - -{reenabling_box.play} - -### See also: - -[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] - -[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch -[error]: http://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/structure.json b/examples/structure.json index 8580133f2f..e87e640056 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,22 +140,22 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "panic", "title": "panic", "children": null }, - { "id": "option_unwrap", "title": "Option & unwrap", "children": [ - { "id": "map", "title": "Combinators: map", "children": null }, - { "id": "and_then", "title": "Combinators: and_then", "children": null }, + { "id": "panic", "title": "`panic`", "children": null }, + { "id": "option_unwrap", "title": "`Option` & `unwrap`", "children": [ + { "id": "map", "title": "Combinators: `map`", "children": null }, + { "id": "and_then", "title": "Combinators: `and_then`", "children": null }, ] }, - { "id": "result", "title": "Result", "children": [ - { "id": "result_map", "title": "map for Result", "children": null }, - { "id": "result_alias", "title": "aliases for Result", "children": null } + { "id": "result", "title": "`Result`", "children": [ + { "id": "result_map", "title": "`map` for `Result`", "children": null }, + { "id": "result_alias", "title": "aliases for `Result`", "children": null } ] }, { "id": "multiple_error_types", "title": "Multiple error types", "children": [ { "id": "early_returns", "title": "Early returns", "children": null }, - { "id": "enter_try", "title": "try!", "children": null } + { "id": "enter_try", "title": "Introducing `try!`", "children": null } ] }, { "id": "define_error_type", "title": "Defining an error type", "children": null }, - { "id": "reenter_try", "title": "Other uses of try!", "children": null }, - { "id": "reenabling_box", "title": "Re-enabling box", "children": null } + { "id": "reenter_try", "title": "Other uses of `try!`", "children": null }, + { "id": "boxing_errors", "title": "`Box`ing errors", "children": null } ] }, { "id": "std", "title": "Std library types", "children": [ { "id": "box", "title": "Box, stack and heap", "children": null }, From 84265d4a32a223cb9f6feff59df31cda63d2207d Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:25:47 -0700 Subject: [PATCH 0521/1122] Reworked example as per minor discussion in #764 Shoutouts to @mdinger for doing the heavy lifting here --- .../early_returns/early_returns.rs | 68 +++++++------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/early_returns.rs b/examples/error/multiple_error_types/early_returns/early_returns.rs index 433699b917..b8ce1a450d 100644 --- a/examples/error/multiple_error_types/early_returns/early_returns.rs +++ b/examples/error/multiple_error_types/early_returns/early_returns.rs @@ -1,51 +1,33 @@ -use std::io::prelude::*; -use std::fs::File; - +// Use `String` as our error type type Result = std::result::Result; -// Setup to make this work. Create two files with some info. Ignore the -// return values because we don't care about them here. -fn setup() { - File::create("a") - .and_then(|mut file| file.write_all(b"grape")) - .unwrap(); - - File::create("b") - .and_then(|mut file| file.write_all(b"fruit")) - .unwrap(); -} - -// Get the data from each file with the data stored in a `Result`. -fn get_data(path: &str) -> Result { - File::open(path) - .map_err(|err| err.to_string()) - .and_then(|mut file| { - let mut contents = String::new(); - - // Read the data into `contents`. - file.read_to_string(&mut contents) - .map_err(|err| err.to_string()) - // Ignore the output `read_to_string` returns and return `contents`. - .map(|_| contents) - }) +fn double_first(vec: Vec<&str>) -> Result { + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + let first = match vec.first() { + Some(first) => first, + None => return Err("Please use a vector with at least one element.".to_owned()) + }; + + // Double the number inside if `parse` works fine. + // Otherwise, map any errors that `parse` yields to `String`. + match first.parse::() { + Ok(i) => Ok(2 * i), + Err(e) => Err(e.to_string()), + } } -// Concat the contents of the two files together into a new `Result`. -fn concat(filename_a: &str, filename_b: &str) -> Result { - let (data_a, data_b) = (get_data(filename_a), get_data(filename_b)); - - data_a.and_then(|a| - // Return `Ok` when both `a` and `b` are `Ok`. Otherwise return - // whichever has the first `Err`. - data_b.and_then(|b| Ok(a + &b)) - ) +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } } fn main() { - setup(); + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; - match concat("a", "b") { - Ok(n) => println!("{}", n), - Err(e) => println!("Error: {}", e), - } -} + print(double_first(empty)); + print(double_first(strings)); +} \ No newline at end of file From c365923164009e321fb9bd3b997364c7c7d8c56b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:29:23 -0700 Subject: [PATCH 0522/1122] Removed working section `result_string_errors` Contained information is now redundant with `multiple_error_types` --- .../result_string_errors/input.md | 11 ------- .../result_string_errors/result_string.rs | 33 ------------------- 2 files changed, 44 deletions(-) delete mode 100644 examples/error/multiple_error_types/result_string_errors/input.md delete mode 100644 examples/error/multiple_error_types/result_string_errors/result_string.rs diff --git a/examples/error/multiple_error_types/result_string_errors/input.md b/examples/error/multiple_error_types/result_string_errors/input.md deleted file mode 100644 index e2a6de3d3d..0000000000 --- a/examples/error/multiple_error_types/result_string_errors/input.md +++ /dev/null @@ -1,11 +0,0 @@ -From our previous example, one method of solving our issue with `unwrap` is to remove it. -In doing so, we must move from implicit to explicit error handling. Since the only -types in play are `Option` and `Result`, we can consider converting both into -`Result`s with the same `Err` type. For our first attempt at this solution, -let's try using a `String` for our error: - -{result_string.play} - -This is not too bad, but it is hardly as nice as the original (it can still be nicer but -we are not there yet). Unfortunately, this approach scales poorly with increasing -numbers of `Result`s, as will be seen in the next example. diff --git a/examples/error/multiple_error_types/result_string_errors/result_string.rs b/examples/error/multiple_error_types/result_string_errors/result_string.rs deleted file mode 100644 index abda6a654f..0000000000 --- a/examples/error/multiple_error_types/result_string_errors/result_string.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - vec.first() - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - .ok_or("Please use a vector with at least one element.".to_owned()) - // Recall that `parse` returns a `Result`. - .and_then(|s| s.parse::() - // Map the errors `parse` yields to `String`. - // The return type is then `Result`. - .map_err(|e| e.to_string()) - // At this point, we can double the number inside. - .map(|i| 2 * i)) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(numbers)); - print(double_first(empty)); - print(double_first(strings)); -} From bc3cf2c9b41052bc2e0be5d5d31c2de8e789928c Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 16:19:54 -0700 Subject: [PATCH 0523/1122] Rename unwrap to option, Add panic_unwrap section New flow is: Error Handling -> Panic & Unwrap -> Option Renamed unwrap to option, as it still teaches that. Moved latter half of Error Handling intro into Panic & Unwrap. This shortens the introduction to Error handling and makes for more accessible information while browsing sections. --- examples/error/{unwrap => option}/input.md | 2 +- .../error/{unwrap/unwrap.rs => option/option.rs} | 0 examples/error/panic_unwrap/input.md | 16 ++++++++++++++++ examples/error/panic_unwrap/panic_unwrap.rs | 12 ++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) rename examples/error/{unwrap => option}/input.md (98%) rename examples/error/{unwrap/unwrap.rs => option/option.rs} (100%) create mode 100644 examples/error/panic_unwrap/input.md create mode 100644 examples/error/panic_unwrap/panic_unwrap.rs diff --git a/examples/error/unwrap/input.md b/examples/error/option/input.md similarity index 98% rename from examples/error/unwrap/input.md rename to examples/error/option/input.md index 119aaf1215..79cd7ad778 100644 --- a/examples/error/unwrap/input.md +++ b/examples/error/option/input.md @@ -16,6 +16,6 @@ meaningful output than explicit handling. In the following example, explicit handling yields a more controlled result while retaining the option to `panic` if desired. -{unwrap.play} +{option.play} [expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/unwrap/unwrap.rs b/examples/error/option/option.rs similarity index 100% rename from examples/error/unwrap/unwrap.rs rename to examples/error/option/option.rs diff --git a/examples/error/panic_unwrap/input.md b/examples/error/panic_unwrap/input.md new file mode 100644 index 0000000000..0dd1051892 --- /dev/null +++ b/examples/error/panic_unwrap/input.md @@ -0,0 +1,16 @@ +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Consider the following example: + +{panic_unwrap.play} + +This shows that we can induce program failure at will, but raises a +question: what happens if the princess is *not* given a gift? We *could* +explicitly test this with a check against the null string (`""`) as we do +with the snake, but this is not reliable. The problem is that programmers do +not habitually test these checks unless required to by the compiler. + +In order for this to be reliable, we'll want the compiler to point out +cases where there may not be a gift. In this chapter, we will learn to use +`Option` to take care of this condition, as well as various functions to +deal with the results of one or more uses of `Option`. diff --git a/examples/error/panic_unwrap/panic_unwrap.rs b/examples/error/panic_unwrap/panic_unwrap.rs new file mode 100644 index 0000000000..bb69620caa --- /dev/null +++ b/examples/error/panic_unwrap/panic_unwrap.rs @@ -0,0 +1,12 @@ +fn give_princess(gift: &str) { + // Princesses hate snakes, so we need to stop if + // she expresses her disapproval! + if gift == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", gift); +} + +fn main() { + give_princess("teddy bear"); + give_princess("snake"); +} From 5d9c6f05f6f1dba1e5adb6479827c5c62533200f Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 16:21:35 -0700 Subject: [PATCH 0524/1122] Oops missed a spot Missed a file in last commit: 92c6461f614db395aad7ee3dbef9435c48f022b7 --- examples/structure.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index 35f18edecb..dc0585ca90 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,7 +140,8 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "unwrap", "title": "Option & unwrap", "children": null }, + { "id": "panic_unwrap", "title": "panic & unwrap", "children": null }, + { "id": "option", "title": "Option", "children": null }, { "id": "map", "title": "map", "children": null }, { "id": "and_then", "title": "and_then", "children": null }, { "id": "result", "title": "Result", "children": [ From b8797ca599ba887dc0d1f8cfc7abd3d86531a6ee Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:46:36 -0700 Subject: [PATCH 0525/1122] Slight restructuring, revisions to chapter intro, relocate text on panic Moved intro to unwrap back to Option (now renamed to Option_unwrap) for better flow: Renamed panic_unwrap to panic. Renamed option to option_unwrap. Slight revisions to text on chapter intro. `map` and `and_then` sections are now children of `Option_unwrap`. "Combinators" added to title to better reflect content. --- examples/error/input.md | 17 ++---------- examples/error/option/input.md | 21 --------------- examples/error/option_unwrap/input.md | 27 +++++++++++++++++++ .../option_unwrap.rs} | 0 examples/error/panic/input.md | 5 ++++ .../panic_unwrap.rs => panic/panic.rs} | 0 examples/error/panic_unwrap/input.md | 16 ----------- examples/structure.json | 13 ++++----- 8 files changed, 41 insertions(+), 58 deletions(-) delete mode 100644 examples/error/option/input.md create mode 100644 examples/error/option_unwrap/input.md rename examples/error/{option/option.rs => option_unwrap/option_unwrap.rs} (100%) create mode 100644 examples/error/panic/input.md rename examples/error/{panic_unwrap/panic_unwrap.rs => panic/panic.rs} (100%) delete mode 100644 examples/error/panic_unwrap/input.md diff --git a/examples/error/input.md b/examples/error/input.md index 6ea85cad1c..4f3744c5b9 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -4,19 +4,6 @@ would clearly be problematic. Error handling allows us to notice and handle those errors in an explicit fashion, saving the rest of the program from potential issues. -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. -Consider the following example: +For additional information on error handling, see the section on error handling in the [official book][book]. -{error.play} - -This shows that we can induce program failure at will, but raises a -question: what happens if the princess is *not* given a gift? We *could* -explicitly test this with a check against the null string (`""`) as we do -with the snake, but this is not reliable. The problem is that programmers do -not habitually test these checks unless required to by the compiler. - -In order for this to be reliable, we'll want the compiler to point out -cases where there may not be a gift. In this chapter, we will learn to use -`Option` to take care of this condition, as well as various functions to -deal with the results of one or more uses of `Option`. +[book]: https://doc.rust-lang.org/book/error-handling.html \ No newline at end of file diff --git a/examples/error/option/input.md b/examples/error/option/input.md deleted file mode 100644 index 79cd7ad778..0000000000 --- a/examples/error/option/input.md +++ /dev/null @@ -1,21 +0,0 @@ -We determined a snake is an inappropriate gift for a princess. But what if -she expected a gift and didn't receive one? That would be just as bad, so -it needs to be handled! In the `std` library, an `enum` called `Option` -is used when absence is a possibility. It manifests itself as one of -two "options": - -* `Some(T)`: An element of type `T` was found -* `None`: No element was found - -These can either be explicitly handled via `match` or implicitly with -`unwrap`. Implicit handling either returns the inner element or `panic`s. - -Note that it's possible to manually customize `panic` with -[expect][expect], but `unwrap` otherwise leaves us with a less -meaningful output than explicit handling. In the following example, -explicit handling yields a more controlled result while retaining the -option to `panic` if desired. - -{option.play} - -[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md new file mode 100644 index 0000000000..d38dcd322d --- /dev/null +++ b/examples/error/option_unwrap/input.md @@ -0,0 +1,27 @@ +In our previous example, we showed that we can induce program failure at +will. To do so, we simply told our program that a snake is an inappropriate +gift. But what if she expected a gift and didn't receive one? That would be +just as bad, so it needs to be handled! + +We *could* explicitly test this with a check against the null string (`""`) +as we do with the snake, but this is not reliable. Instead, we want the +compiler to point out cases where there may not be a gift. + +In the `std` library, an `enum` called `Option` is used when absence is a +possibility. It manifests itself as one of two "options": + +* `Some(T)`: An element of type `T` was found +* `None`: No element was found + +These can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling either returns the inner element or `panic`s. + +Note that it's possible to manually customize `panic` with +[expect][expect], but `unwrap` otherwise leaves us with a less +meaningful output than explicit handling. In the following example, +explicit handling yields a more controlled result while retaining the +option to `panic` if desired. + +{option_unwrap.play} + +[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option/option.rs b/examples/error/option_unwrap/option_unwrap.rs similarity index 100% rename from examples/error/option/option.rs rename to examples/error/option_unwrap/option_unwrap.rs diff --git a/examples/error/panic/input.md b/examples/error/panic/input.md new file mode 100644 index 0000000000..9703a3c370 --- /dev/null +++ b/examples/error/panic/input.md @@ -0,0 +1,5 @@ +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Here, we explicitly called `panic` on our error condition: + +{panic.play} diff --git a/examples/error/panic_unwrap/panic_unwrap.rs b/examples/error/panic/panic.rs similarity index 100% rename from examples/error/panic_unwrap/panic_unwrap.rs rename to examples/error/panic/panic.rs diff --git a/examples/error/panic_unwrap/input.md b/examples/error/panic_unwrap/input.md deleted file mode 100644 index 0dd1051892..0000000000 --- a/examples/error/panic_unwrap/input.md +++ /dev/null @@ -1,16 +0,0 @@ -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. -Consider the following example: - -{panic_unwrap.play} - -This shows that we can induce program failure at will, but raises a -question: what happens if the princess is *not* given a gift? We *could* -explicitly test this with a check against the null string (`""`) as we do -with the snake, but this is not reliable. The problem is that programmers do -not habitually test these checks unless required to by the compiler. - -In order for this to be reliable, we'll want the compiler to point out -cases where there may not be a gift. In this chapter, we will learn to use -`Option` to take care of this condition, as well as various functions to -deal with the results of one or more uses of `Option`. diff --git a/examples/structure.json b/examples/structure.json index dc0585ca90..9e30bc2af1 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,10 +140,11 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "panic_unwrap", "title": "panic & unwrap", "children": null }, - { "id": "option", "title": "Option", "children": null }, - { "id": "map", "title": "map", "children": null }, - { "id": "and_then", "title": "and_then", "children": null }, + { "id": "panic", "title": "panic", "children": null }, + { "id": "option_unwrap", "title": "Option & unwrap", "children": [ + { "id": "map", "title": "Combinators: map", "children": null }, + { "id": "and_then", "title": "Combinators: and_then", "children": null }, + ] }, { "id": "result", "title": "Result", "children": [ { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "aliases for Result", "children": null } @@ -151,10 +152,10 @@ { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, - { "id": "enter_try", "title": "Enter try!", "children": null } + { "id": "enter_try", "title": "try!", "children": null } ] }, { "id": "limits_of_strings", "title": "The limits of strings", "children": null }, - { "id": "reenter_try", "title": "Re-enter try!", "children": null }, + { "id": "reenter_try", "title": "Other uses of try!", "children": null }, { "id": "reenabling_box", "title": "Re-enabling box", "children": null } ] }, { "id": "std", "title": "Std library types", "children": [ From c157c892c08ad01de2d6734016f4a29b4cd21ace Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:47:23 -0700 Subject: [PATCH 0526/1122] Removed code from chapter intro Removed panic code example from chapter intro. This information currently exists in `panic`. --- examples/error/error.rs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 examples/error/error.rs diff --git a/examples/error/error.rs b/examples/error/error.rs deleted file mode 100644 index bb69620caa..0000000000 --- a/examples/error/error.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if - // she expresses her disapproval! - if gift == "snake" { panic!("AAAaaaaa!!!!"); } - - println!("I love {}s!!!!!", gift); -} - -fn main() { - give_princess("teddy bear"); - give_princess("snake"); -} From 45e5c304c51bac4a012338998d47f6a51b2a4bbb Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 27 Jun 2016 17:50:13 -0700 Subject: [PATCH 0527/1122] Minor grammar fixes --- examples/error/option_unwrap/input.md | 6 +++--- examples/error/panic/input.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md index d38dcd322d..96c19d0900 100644 --- a/examples/error/option_unwrap/input.md +++ b/examples/error/option_unwrap/input.md @@ -1,13 +1,13 @@ In our previous example, we showed that we can induce program failure at will. To do so, we simply told our program that a snake is an inappropriate -gift. But what if she expected a gift and didn't receive one? That would be -just as bad, so it needs to be handled! +gift. But what if the princess expected a gift and didn't receive one? That +would be just as bad, so it needs to be handled! We *could* explicitly test this with a check against the null string (`""`) as we do with the snake, but this is not reliable. Instead, we want the compiler to point out cases where there may not be a gift. -In the `std` library, an `enum` called `Option` is used when absence is a +An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": * `Some(T)`: An element of type `T` was found diff --git a/examples/error/panic/input.md b/examples/error/panic/input.md index 9703a3c370..87c4f544da 100644 --- a/examples/error/panic/input.md +++ b/examples/error/panic/input.md @@ -1,5 +1,5 @@ The simplest error handling mechanism we will see is `panic`. It prints an error message, starts unwinding the task, and usually exits the program. -Here, we explicitly called `panic` on our error condition: +Here, we explicitly call `panic` on our error condition: {panic.play} From fadb153410f803aac74be2aeb5c0fa8441c14eeb Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 7 Jul 2016 18:10:50 -0700 Subject: [PATCH 0528/1122] Minor editing Change wording and shuffling some text around for line length --- examples/error/input.md | 8 ++++---- examples/error/panic/panic.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/error/input.md b/examples/error/input.md index 4f3744c5b9..46175a4393 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -1,9 +1,9 @@ Error handling is the process of handling the possibility of failure. For example, failing to read a file and then continuing to use that *bad* input -would clearly be problematic. Error handling allows us to notice and handle -those errors in an explicit fashion, saving the rest of the program from -potential issues. +would clearly be problematic. Noticing and managing those errors in an +explicit fashion saves the rest of the program from potential issues. -For additional information on error handling, see the section on error handling in the [official book][book]. +For additional information on error handling, see the section on error +handling in the [official book][book]. [book]: https://doc.rust-lang.org/book/error-handling.html \ No newline at end of file diff --git a/examples/error/panic/panic.rs b/examples/error/panic/panic.rs index bb69620caa..26d8f9f94d 100644 --- a/examples/error/panic/panic.rs +++ b/examples/error/panic/panic.rs @@ -1,6 +1,5 @@ fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if - // she expresses her disapproval! + // Princesses hate snakes, so we need to stop if she disapproves! if gift == "snake" { panic!("AAAaaaaa!!!!"); } println!("I love {}s!!!!!", gift); From a232ff5311a5c6e3023596d2312c95d4655c7d95 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 7 Jul 2016 18:13:29 -0700 Subject: [PATCH 0529/1122] Update `option_unwrap`, `map`, and `and_then` Moved `map` and `and_then` into `option_unwrap` to match new chapter layout Condensed text in markdown files Reorganized "See also" sections Simplify some language in code examples --- examples/error/and_then/input.md | 20 -------------- examples/error/map/input.md | 18 ------------- .../{ => option_unwrap}/and_then/and_then.rs | 0 .../error/option_unwrap/and_then/input.md | 21 +++++++++++++++ examples/error/option_unwrap/input.md | 27 +++++++++---------- examples/error/option_unwrap/map/input.md | 22 +++++++++++++++ examples/error/{ => option_unwrap}/map/map.rs | 13 ++++----- examples/error/option_unwrap/option_unwrap.rs | 9 ++++--- 8 files changed, 68 insertions(+), 62 deletions(-) delete mode 100644 examples/error/and_then/input.md delete mode 100644 examples/error/map/input.md rename examples/error/{ => option_unwrap}/and_then/and_then.rs (100%) create mode 100644 examples/error/option_unwrap/and_then/input.md create mode 100644 examples/error/option_unwrap/map/input.md rename examples/error/{ => option_unwrap}/map/map.rs (76%) diff --git a/examples/error/and_then/input.md b/examples/error/and_then/input.md deleted file mode 100644 index f28d828394..0000000000 --- a/examples/error/and_then/input.md +++ /dev/null @@ -1,20 +0,0 @@ -`map()` was described as a chainable way to simplify `match` statements. -However, using `map()` on a function that returns an `Option` results -in the nested `Option>`. Chaining multiple calls together can -then become confusing. - -That's where `and_then()` comes in. Known in some languages as flatmap, `and_then()` calls its function input with the wrapped value or returns `None` if the `Option` is `None`. - -In the following example, `cookable_v2()` results in an `Option`. -Using `map()` instead of `and_then()` would have given an `Option>`, -which is an invalid type for `eat()`. - -{and_then.play} - -### See also: - -[`Option`][option], [`Option::map()`][map], and [`Option::and_then()`][and_then] - -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map -[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/map/input.md b/examples/error/map/input.md deleted file mode 100644 index 7f5fbdc7e5..0000000000 --- a/examples/error/map/input.md +++ /dev/null @@ -1,18 +0,0 @@ -`match` is a valid method for handling `Option`s. However, you may eventually -find heavy usage tedious; this is the case especially with operations that -are only valid with an input. - -For situations where a simplistic mapping of `Some -> Some` and -`None -> None` is needed, `Option` has a built in method called `map()`. - -Multiple `map()` calls can be chained together for even more flexibility. -In the following example, `process()` easily replaces all functions previous -to it while staying compact. - -{map.play} - -### See also: - -[closures][closures] - -[closures]: /fn/closures.html diff --git a/examples/error/and_then/and_then.rs b/examples/error/option_unwrap/and_then/and_then.rs similarity index 100% rename from examples/error/and_then/and_then.rs rename to examples/error/option_unwrap/and_then/and_then.rs diff --git a/examples/error/option_unwrap/and_then/input.md b/examples/error/option_unwrap/and_then/input.md new file mode 100644 index 0000000000..de4fa46344 --- /dev/null +++ b/examples/error/option_unwrap/and_then/input.md @@ -0,0 +1,21 @@ +`map()` was described as a chainable way to simplify `match` statements. +However, using `map()` on a function that returns an `Option` results +in the nested `Option>`. Chaining multiple calls together can +then become confusing. That's where another combinator called `and_then()`, +known in some languages as flatmap, comes in. + +`and_then()` calls its function input with the wrapped value and returns the result. If the `Option` is `None`, then it returns `None` instead. + +In the following example, `cookable_v2()` results in an `Option`. +Using `map()` instead of `and_then()` would have given an +`Option>`, which is an invalid type for `eat()`. + +{and_then.play} + +### See also: + +[closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] + +[closures]: /fn/closures.html +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md index 96c19d0900..e15da58adc 100644 --- a/examples/error/option_unwrap/input.md +++ b/examples/error/option_unwrap/input.md @@ -1,11 +1,11 @@ -In our previous example, we showed that we can induce program failure at -will. To do so, we simply told our program that a snake is an inappropriate -gift. But what if the princess expected a gift and didn't receive one? That -would be just as bad, so it needs to be handled! +In the last example, we showed that we can induce program failure at will. +We told our program to `panic` if the princess received an inappropriate +gift - a snake. But what if the princess expected a gift and didn't receive +one? That case would be just as bad, so it needs to be handled! -We *could* explicitly test this with a check against the null string (`""`) -as we do with the snake, but this is not reliable. Instead, we want the -compiler to point out cases where there may not be a gift. +We *could* test this against the null string (`""`) as we do with a snake. +Since we're using Rust, let's instead have the compiler point out cases +where there's no gift. An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": @@ -13,14 +13,13 @@ possibility. It manifests itself as one of two "options": * `Some(T)`: An element of type `T` was found * `None`: No element was found -These can either be explicitly handled via `match` or implicitly with -`unwrap`. Implicit handling either returns the inner element or `panic`s. +These cases can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling will either return the inner element or `panic`. -Note that it's possible to manually customize `panic` with -[expect][expect], but `unwrap` otherwise leaves us with a less -meaningful output than explicit handling. In the following example, -explicit handling yields a more controlled result while retaining the -option to `panic` if desired. +Note that it's possible to manually customize `panic` with [expect][expect], +but `unwrap` otherwise leaves us with a less meaningful output than explicit +handling. In the following example, explicit handling yields a more +controlled result while retaining the option to `panic` if desired. {option_unwrap.play} diff --git a/examples/error/option_unwrap/map/input.md b/examples/error/option_unwrap/map/input.md new file mode 100644 index 0000000000..31d7f9a1cb --- /dev/null +++ b/examples/error/option_unwrap/map/input.md @@ -0,0 +1,22 @@ +`match` is a valid method for handling `Option`s. However, you may +eventually find heavy usage tedious, especially with operations only valid +with an input. In these cases, [combinators][combinators] can be used to +manage control flow in a modular fashion. + +`Option` has a built in method called `map()`, a combinator for the simple +mapping of `Some -> Some` and `None -> None`. Multiple `map()` calls can be +chained together for even more flexibility. + +In the following example, `process()` replaces all functions previous +to it while staying compact. + +{map.play} + +### See also: + +[closures][closures], [`Option`][option], [`Option::map()`][map] + +[combinators]: https://doc.rust-lang.org/book/glossary.html#combinators +[closures]: /fn/closures.html +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/examples/error/map/map.rs b/examples/error/option_unwrap/map/map.rs similarity index 76% rename from examples/error/map/map.rs rename to examples/error/option_unwrap/map/map.rs index 9c09d72e77..e851bf979a 100644 --- a/examples/error/map/map.rs +++ b/examples/error/option_unwrap/map/map.rs @@ -6,7 +6,7 @@ #[derive(Debug)] struct Chopped(Food); #[derive(Debug)] struct Cooked(Food); -// Peeling food. If there isn't any, then just return `None`. +// Peeling food. If there isn't any, then return `None`. // Otherwise, return the peeled food. fn peel(food: Option) -> Option { match food { @@ -15,7 +15,8 @@ fn peel(food: Option) -> Option { } } -// Like above, we need to know if the peeled food exists before chopping. +// Chopping food. If there isn't any, then return `None`. +// Otherwise, return the chopped food. fn chop(peeled: Option) -> Option { match peeled { Some(Peeled(food)) => Some(Chopped(food)), @@ -23,20 +24,20 @@ fn chop(peeled: Option) -> Option { } } -// Similar to previous checks, but using `map()` instead of `match`. +// Cooking food. Here, we showcase `map()` instead of `match` for case handling. fn cook(chopped: Option) -> Option { chopped.map(|Chopped(food)| Cooked(food)) } -// Alternatively, we can chain multiple uses of `map()` to simplify -// the above process. +// A function to peel, chop, and cook food all in sequence. +// We chain multiple uses of `map()` to simplify the code. fn process(food: Option) -> Option { food.map(|f| Peeled(f)) .map(|Peeled(f)| Chopped(f)) .map(|Chopped(f)| Cooked(f)) } -// It's important to know whether there's food or not before trying to eat it! +// Check whether there's food or not before trying to eat it! fn eat(food: Option) { match food { Some(food) => println!("Mmm. I love {:?}", food), diff --git a/examples/error/option_unwrap/option_unwrap.rs b/examples/error/option_unwrap/option_unwrap.rs index 898728cd46..8ac6ad50fb 100644 --- a/examples/error/option_unwrap/option_unwrap.rs +++ b/examples/error/option_unwrap/option_unwrap.rs @@ -1,5 +1,5 @@ -// The commoner has seen it all, and handles situations well. -// All gifts are handled manually using `match`. +// The commoner has seen it all, and can handle any gift well. +// All gifts are handled explicitly using `match`. fn give_commoner(gift: Option<&str>) { // Specify a course of action for each case. match gift { @@ -10,8 +10,9 @@ fn give_commoner(gift: Option<&str>) { } // Our sheltered princess will `panic` at the sight of snakes. +// All gifts are handled implicitly using `unwrap`. fn give_princess(gift: Option<&str>) { - // Using `unwrap` returns a `panic` when it receives a `None`. + // `unwrap` returns a `panic` when it receives a `None`. let inside = gift.unwrap(); if inside == "snake" { panic!("AAAaaaaa!!!!"); } @@ -19,7 +20,7 @@ fn give_princess(gift: Option<&str>) { } fn main() { - let food = Some("chicken"); + let food = Some("cabbage"); let snake = Some("snake"); let void = None; From 42d3ebf5db7330e60fc5190ccd6f2df59afdeedf Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Sat, 9 Jul 2016 00:19:19 -0700 Subject: [PATCH 0530/1122] Updated `Result` Reframed `Result` in the context of `Option` Moved some text from code comment to .md file --- examples/error/result/input.md | 34 ++++++++++++++++++++++----------- examples/error/result/result.rs | 4 +--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/error/result/input.md b/examples/error/result/input.md index b9e03940b9..1dc778ce2f 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -1,22 +1,34 @@ -Previously, we have used the `Option` type to annotate that absence is a possibility. This -absence sometimes appears as an error, such as when `None` is unwrapped. -When multiple failure points may exist, an `Option` can be replaced by the -more general `Result` type. A `Result` has these variants: +[`Result`][result] is a richer version of the [`Option`][option] type that +describes possible *error* instead of possible *absence*. + +That is, `Result` could have one of two outcomes: * `Ok`: An element `T` was found * `Err`: An error was found with element `E` -Similar to `Option`, `Result` also contains the `unwrap()` method which yields the element -`T` or calls `panic!()`. So far, this should seem similar to `Option`: +By convention, the expected outcome is “Ok” while the unexpected outcome is “Err”. -{result.play} +Like `Option`, `Result` has many methods associated with it. `unwrap()`, for +example, either yields the element `T` or `panic`s. For case handling, +there are many combinators between `Result` and `Option` that overlap. -Clearly, panicking on an `Err` leaves an unhelpful error message. Luckily for us, -the upcoming combinators are available to help us with errors. +In working with Rust, you will likely encounter methods that return the +`Result` type, such as the [`parse()`][parse] method. It might not always +be possible to parse a string into the other type, so `parse()` returns a +`Result` indicating possible failure. +Let's see what happens when we successfully and unsuccessfully `parse()` a string: + +{result.play} -### See also: +In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` +to `panic` on. Additionally, the `panic` exits our program and provides an +unpleasant error message. -[`Result`][result] +To improve the quality of our error message, we'll need to be more specific +about the return type. Additionally, we should consider explicitly handling +the error. +[option]: http://doc.rust-lang.org/std/option/enum.Option.html [result]: http://doc.rust-lang.org/std/result/enum.Result.html +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/examples/error/result/result.rs b/examples/error/result/result.rs index 9d98ebfba1..baa9d3faef 100644 --- a/examples/error/result/result.rs +++ b/examples/error/result/result.rs @@ -1,7 +1,5 @@ fn double_number(number_str: &str) -> i32 { - // It might not always be possible to parse a string into the other type, - // so `parse()` returns a `Result` indicating possible failure. Let's - // try using `unwrap()` to get the number out. Will it bite us? + // Let's try using `unwrap()` to get the number out. Will it bite us? 2 * number_str.parse::().unwrap() } From 2ab1038ec602d4ae0a2465c003fb3738d8b25f3a Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:05:53 -0700 Subject: [PATCH 0531/1122] Minor grammar change to Result Condensed two sentences for readability --- examples/error/result/input.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/error/result/input.md b/examples/error/result/input.md index 1dc778ce2f..13072316b8 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -25,9 +25,8 @@ In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` to `panic` on. Additionally, the `panic` exits our program and provides an unpleasant error message. -To improve the quality of our error message, we'll need to be more specific -about the return type. Additionally, we should consider explicitly handling -the error. +To improve the quality of our error message, we should be more specific +about the return type and consider explicitly handling the error. [option]: http://doc.rust-lang.org/std/option/enum.Option.html [result]: http://doc.rust-lang.org/std/result/enum.Result.html From 2b9a3323b10e4e43e0a608e5ce4980c2b6e4632b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:31:56 -0700 Subject: [PATCH 0532/1122] Condense 16.6 text and code comments Renamed to "Defining an error type" to improve searching. Updated filenames and structure.json to reflect the change. Reduced wordiness of code comments and block text. --- .../define_error_type.rs} | 25 ++++++++--------- examples/error/define_error_type/input.md | 27 +++++++++++++++++++ examples/error/limits_of_strings/input.md | 27 ------------------- examples/structure.json | 2 +- 4 files changed, 39 insertions(+), 42 deletions(-) rename examples/error/{limits_of_strings/rethink.rs => define_error_type/define_error_type.rs} (56%) create mode 100644 examples/error/define_error_type/input.md delete mode 100644 examples/error/limits_of_strings/input.md diff --git a/examples/error/limits_of_strings/rethink.rs b/examples/error/define_error_type/define_error_type.rs similarity index 56% rename from examples/error/limits_of_strings/rethink.rs rename to examples/error/define_error_type/define_error_type.rs index 868dc69a4f..0802ec377b 100644 --- a/examples/error/limits_of_strings/rethink.rs +++ b/examples/error/define_error_type/define_error_type.rs @@ -4,31 +4,28 @@ use std::fmt; type Result = std::result::Result; #[derive(Debug)] -// Define our error types. These may be customized however is useful for our error -// handling cases. Now we will be able to defer to the underlying tools error -// implementation, write our own errors, or something in between. +// Define our error types. These may be customized for our error handling cases. +// Now we will be able to write our own errors, defer to an underlying error +// implementation, or do something in between. enum DoubleError { // We don't require any extra info to detail this error. EmptyVec, - // We will defer to the parse error implementation for their error. Supplying extra - // info would require adding more data to the type. + // We will defer to the parse error implementation for their error. + // Supplying extra info requires adding more data to the type. Parse(ParseIntError), } -// How the type is displayed is completely separate from where the errors are generated. -// We do not need to be concerned that the display style will clutter the complex logic -// our utility requires. They are separate matters which are handled separately. +// Generation of an error is completely separate from how it is displayed. +// There's no need to be concerned about cluttering complex logic with the display style. // -// We don't store extra info about the errors. If we had desired, for example, to state -// which string failed to parse then we can't without modifying our types to carry that -// information accordingly. +// Note that we don't store any extra info about the errors. This means we can't state +// which string failed to parse without modifying our types to carry that information. impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - // This is a wrapper so defer to the underlying types' own implementation - // of `fmt`. + write!(f, "Please use a vector with at least one element."), + // This is a wrapper, so defer to the underlying types' implementation of `fmt`. DoubleError::Parse(ref e) => e.fmt(f), } } diff --git a/examples/error/define_error_type/input.md b/examples/error/define_error_type/input.md new file mode 100644 index 0000000000..0b51ad74dc --- /dev/null +++ b/examples/error/define_error_type/input.md @@ -0,0 +1,27 @@ +Rust allows us to define our own error types. Up until now, we've been using +`String`s as errors. However, they are somewhat limiting as an error type. + +In general, a "good" error type: + +* Represents different errors with the same type +* Presents nice error messages to the user +* Is easy to compare with other types + - Good: `Err(EmptyVec)` + - Bad: `Err("Please use a vector with at least one element".to_owned())` +* Can hold information about the error + - Good: `Err(BadChar(c, position))` + - Bad: `Err("+ cannot be used here".to_owned())` + +Note that a `String` fulfills the first two criteria, but not the last two. +This makes `String` errors verbose to create and difficult to react to. +It should not be necessary to pollute logic heavy code with `String` formatting simply to display nicely. + +{define_error_type.play} + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/error/limits_of_strings/input.md b/examples/error/limits_of_strings/input.md deleted file mode 100644 index 5bc09e9f51..0000000000 --- a/examples/error/limits_of_strings/input.md +++ /dev/null @@ -1,27 +0,0 @@ -We have been using `Strings` as errors for a while. In fact, this is somewhat limiting as -an error type. Below are the criteria for a good error type. `String` nicely fulfills the first -two but not the second two: - -* Represents different errors with the same type -* Presents nice error messages to the user -* Is easily type comparable. Consider comparing these two types: - - `Err("Please use a vector with at least one element".to_owned())` - - `Err(EmptyVec)` -* Can hold information about the error. Compare: - - `Err("+ cannot be used here".to_owned())` - - `Err(BadChar(c, position))` - -This makes `String` errors both difficult to react to and verbose to create. In fact, a nice -looking error message has nothing to do with how the type is structured. It is simply a -consequence of `Display` being implemented for the type. It should not be necessary to -pollute logic heavy code with `String` formatting simply for nice error messages. - -{rethink.play} - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html -[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/structure.json b/examples/structure.json index 9e30bc2af1..8be0748c13 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -154,7 +154,7 @@ { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, { "id": "enter_try", "title": "try!", "children": null } ] }, - { "id": "limits_of_strings", "title": "The limits of strings", "children": null }, + { "id": "define_error_type", "title": "Defining an error type", "children": null }, { "id": "reenter_try", "title": "Other uses of try!", "children": null }, { "id": "reenabling_box", "title": "Re-enabling box", "children": null } ] }, From c800896143695fb2d067f3fc71c0c0bc8d12583c Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 16:54:22 -0700 Subject: [PATCH 0533/1122] Condensed 16.7 text and code comments, minor grammar change to define_error_type.rs reenter_try: Condensed 16.7 text and code comments for better readability and clearer points. Renamed rethink.rs to reenter_try.rs define_error_type.rs: Reverted a text change in the error message --- .../define_error_type/define_error_type.rs | 2 +- examples/error/reenter_try/input.md | 64 ++++++++++--------- .../{rethink.rs => reenter_try.rs} | 6 +- 3 files changed, 39 insertions(+), 33 deletions(-) rename examples/error/reenter_try/{rethink.rs => reenter_try.rs} (92%) diff --git a/examples/error/define_error_type/define_error_type.rs b/examples/error/define_error_type/define_error_type.rs index 0802ec377b..dc04bce925 100644 --- a/examples/error/define_error_type/define_error_type.rs +++ b/examples/error/define_error_type/define_error_type.rs @@ -24,7 +24,7 @@ impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { DoubleError::EmptyVec => - write!(f, "Please use a vector with at least one element."), + write!(f, "please use a vector with at least one element"), // This is a wrapper, so defer to the underlying types' implementation of `fmt`. DoubleError::Parse(ref e) => e.fmt(f), } diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index 0be7b70058..e298ba910d 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -1,38 +1,44 @@ -If you will notice from the previous example, when we call `parse`, the immediate reaction -is to `map` the error from a library error into our new custom error type. +Notice in the previous example that our immediate reaction to calling +`parse` is to `map` the error from a library error into our new custom +error type: ```rust .and_then(|s| s.parse::() .map_err(DoubleError::Parse) ``` -This is a very simple and also common operation so it would be convenient if eliding it -would work but alas, it does not. `and_then` is not sufficiently flexible that it can handle -this; `try!` is though. - -`try!` has previously been explained as either `unwrap` or `return Err(err)` which is only -`93%` correct. It actually means `unwrap` or `return Err(From::from(err))`. Since `From::from` -is a conversion utility between different types, this means if you `try!` something where the -error is convertible to the return type, it will convert automatically. This means, if we -rewrite this example with `try!` when `From::from` is implemented for our error type, -the `map_err` will go away: - -{rethink.play} - -This is actually fairly clean now. If you compare it with the original `panic`, it is very similar -to replacing the `unwrap` calls with `try!` except that the return types are `Result` and so -they must be destructured at the top level. - -However, do not expect error handling of this sort to replace all usage of `unwrap` in -practice. Error handling of this sort tripled our code line count and cannot really be -called simple even if this is heavily biased by the small code size. Indeed, moving a 1000 line -library from `unwrap` to more proper error handling might be feasible in an additional -100 lines of code though the necessary refractoring definitely would not be trivial. - -This is a very reasonable place to be. Many libraries might get away with only -implementing `Display` and then adding `From` on an as needed basis. A serious library -though will have users with certain expections about how it should implement error handling. -In those cases, the error handling will need to be taken one step further. +Since this is a simple and common operation, it would be convenient if it +could be elided. Alas, because `and_then` is not sufficiently flexible, it +cannot. However, we can instead use `try!`. + +`try!` was previously explained as either `unwrap` or `return Err(err)`. +This is only mostly true. It actually means `unwrap` or +`return Err(From::from(err))`. Since `From::from` is a conversion utility +between different types, this means that if you `try!` where the error is +convertible to the return type, it will convert automatically. + +Here, we rewrite the previous example using `try!` As a result, the +`map_err` will go away when `From::from` is implemented for our error type: + +{reenter_try.play} + +This is actually fairly clean now. Compared with the original `panic`, it +is very similar to replacing the `unwrap` calls with `try!` except that the +return types are `Result`. As a result, they must be destructured at the +top level. + +Note that you should not expect error handling of this sort to always +replace `unwrap`. This type of error handling tripled our line count and +cannot really be considered simple (even when heavily biased by the small +code size). + +Indeed, moving a 1000 line library from `unwrap` to more proper error +handling might be feasible in an additional 100 lines of code. However, the +necessary refactoring would most definitely not be trivial. + +Many libraries might get away with only implementing `Display` and +adding `From` on an as needed basis. However, more serious libraries will +eventually need to meet higher expections of error handling implementation. ### See also: diff --git a/examples/error/reenter_try/rethink.rs b/examples/error/reenter_try/reenter_try.rs similarity index 92% rename from examples/error/reenter_try/rethink.rs rename to examples/error/reenter_try/reenter_try.rs index 38533ce91c..da7aaeb9fd 100644 --- a/examples/error/reenter_try/rethink.rs +++ b/examples/error/reenter_try/reenter_try.rs @@ -9,9 +9,9 @@ enum DoubleError { Parse(ParseIntError), } -// Implement the conversion from `ParseIntError` to `DoubleError`. This will be -// automatically called by `try!` if a `ParseIntError` needs converting into -// a `DoubleError`. +// Implement the conversion from `ParseIntError` to `DoubleError`. +// This will be automatically called by `try!` if a `ParseIntError` +// needs to be converted into a `DoubleError`. impl From for DoubleError { fn from(err: ParseIntError) -> DoubleError { DoubleError::Parse(err) From 9e2cac50bdd0ef4433084a7533f613186daf9ff1 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 17:13:58 -0700 Subject: [PATCH 0534/1122] Updated "map for Result" input.md: Reduced wordiness and removed some redundant information that shows up in the previous section. result_map.rs: Renamed from result.rs Minor changes for grammar/readability --- examples/error/result/result_map/input.md | 31 ++++++++----------- .../result_map/{result.rs => result_map.rs} | 5 ++- 2 files changed, 15 insertions(+), 21 deletions(-) rename examples/error/result/result_map/{result.rs => result_map.rs} (82%) diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md index 00641072a5..0c4214ad13 100644 --- a/examples/error/result/result_map/input.md +++ b/examples/error/result/result_map/input.md @@ -1,24 +1,19 @@ -Panicking on `unwrap()` in the previous example gave us an unhelpful error message. -To avoid that, we need to be more specific about the return type. In that example, -recall that the regular element is of type `i32`. To determine the `Err` type, we -look to `parse()`. `parse()` is implemented with the [`FromStr trait`][from_str] -for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. +Panicking in the previous example gave us an unhelpful error message. +To avoid that, we need to be more specific about the return type. There, the +regular element is of type `i32`. -In the example below, note that using the straightforward `match` statement leads to -more cumbersome code. As it turns out, the `map` method we used with `Option` -is also implemented for `Result`. +To determine the `Err` type, we look to +`parse()`, which is implemented with the [`FromStr`][from_str] trait for +[`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. -{result.play} +In the example below, the straightforward `match` statement leads to code +that is overall more cumbersome. Luckily, the `map` method of `Option` is +one of many combinators also implemented for `Result`. [`enum.Result`][result] +contains a complete listing. -Much like `Option`, `Result` implements combinators besides `map`, such as `and_then` -and `unwrap_or`. This even includes those that specifically handle errors, like `map_err`. -[`Result`][result] contains the complete listing. +{result_map.play} -### See also: - -[`i32`][i32], [`FromStr`][from_str], and [`ParseIntErr`][parse_int_error] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html [from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html [i32]: http://doc.rust-lang.org/std/primitive.i32.html +[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html +[result]: http://doc.rust-lang.org/std/result/enum.Result.html diff --git a/examples/error/result/result_map/result.rs b/examples/error/result/result_map/result_map.rs similarity index 82% rename from examples/error/result/result_map/result.rs rename to examples/error/result/result_map/result_map.rs index bb009b24c2..fbf7110bd8 100644 --- a/examples/error/result/result_map/result.rs +++ b/examples/error/result/result_map/result_map.rs @@ -1,7 +1,6 @@ use std::num::ParseIntError; -// With the return type rewritten, we proceed to use pattern matching without -// `unwrap()`, but it is tedious. +// With the return type rewritten, we use pattern matching without `unwrap()`. fn double_number(number_str: &str) -> Result { match number_str.parse::() { Ok(n) => Ok(2 * n), @@ -28,7 +27,7 @@ fn main() { let twenty = double_number("10"); print(twenty); - // The following now provides a much more useful error message + // The following now provides a much more helpful error message. let tt = double_number_map("t"); print(tt); } From c36864c719747033c8ac99e25df441a5078d94cb Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 22 Jul 2016 19:47:28 -0700 Subject: [PATCH 0535/1122] Updated "aliases for Result" alias.rs: Minor grammar change input.md: Condensed and reordered text for readability --- examples/error/result/result_alias/alias.rs | 2 +- examples/error/result/result_alias/input.md | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs index 105f1ebe42..3a948887a4 100644 --- a/examples/error/result/result_alias/alias.rs +++ b/examples/error/result/result_alias/alias.rs @@ -4,7 +4,7 @@ use std::result; // Define a generic alias for a `Result` with the error type `ParseIntError`. type AliasedResult = result::Result; -// Use the alias defined above to refer to our specific `Result` type. +// Use the above alias to refer to our specific `Result` type. fn double_number(number_str: &str) -> AliasedResult { number_str.parse::().map(|n| 2 * n) } diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md index 9d2e67c311..5085e5dc80 100644 --- a/examples/error/result/result_alias/input.md +++ b/examples/error/result/result_alias/input.md @@ -1,13 +1,14 @@ How about when we want to reuse a specific `Result` type many times? -It quickly becomes tedious to write out the full type name, but recall that Rust allows -us to create [aliases][typealias]. A generic alias may conveniently be defined for the -specific `Result` in question: - -{alias.play} +Recall that Rust allows us to create [aliases][typealias]. Conveniently, +we can define one for the specific `Result` in question. At a module level, creating aliases can be particularly helpful. Errors -found in a specific module often have the same `Err` type, so a single alias can succinctly -define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! +found in a specific module often have the same `Err` type, so a single alias +can succinctly define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! + +Here's a quick example to show off the syntax: + +{alias.play} ### See also: From 739aa3177b1756c7f746c4ca351a88a966fa7382 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:00:24 -0700 Subject: [PATCH 0536/1122] Renamed 16.5, combined content mostly with 16.5.1 Renamed 16.5 for better searching: Options with Results -> Multiple error types Updated structure.json, option_result.rs to match input.md: Reduced wordiness of explanations Reworked code example to a snippet New code example reflects the example of old 16.5.1 --Reasoning: no longer requires flipping between pages to see the difference when replacing .unwrap with explicit error handling Added See also for ok_or and map_err, as they are used in the new code example, but not explicitly defined in the text --- examples/error/option_with_result/input.md | 49 ++++++++++++++----- .../multiple_error_types.rs | 30 ++++++++++++ examples/structure.json | 4 +- 3 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 examples/error/option_with_result/multiple_error_types.rs diff --git a/examples/error/option_with_result/input.md b/examples/error/option_with_result/input.md index e1112363b8..9201d57429 100644 --- a/examples/error/option_with_result/input.md +++ b/examples/error/option_with_result/input.md @@ -1,16 +1,41 @@ -In the following sections, we will see how to combine separate operations returning -`Option` and `Result` into a single operation that returns whichever one makes the -most sense. +The previous examples have always been very convenient; `Result`s interact +with other `Result`s and `Option`s interact with other `Option`s. -The previous examples have always been very convenient; a `Result` interacted -with another `Result` and an `Option` interacted with another `Option`. Unfortunately, -it's not always that easy. An `Option` may have to interact with a `Result`, and a -`Result` may have to interact with a `Result`. +Sometimes an `Option` needs to interact with a `Result`, or a `Result` +needs to interact with a `Result`. In those cases, we want to +handle the *composition of distinct error types*. -To start us off, the example below uses `Vec::first` and `parse::` with `unwrap` to -generate errors. `Vec::first` returns an `Option`, while `parse::` -returns a `Result`. +In the following code, two instances of `unwrap` generate different error +types. `Vec::first` returns an `Option`, while `parse::` returns a +`Result`: -Note that this code "works", but is meant to showcase **improper** error handling: +```rust +fn double_first(vec: Vec<&str>) -> i32 { + let first = vec.first().unwrap(); // Generate error 1 + 2 * first.parse::().unwrap() // Generate error 2 +} -{option_result.play} +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {}", double_first(empty)); + // Error 1: the input vector is empty + + println!("The first doubled is {}", double_first(strings)); + // Error 2: the element doesn't parse to a number +} +``` + +Using our knowledge of combinators, we can rewrite the above to explicitly +handle errors. In doing so, we convert both `Option`s and `Result`s into +`Result`s, and map them to the same error type (`String`): + +{multiple_error_types.play} + +### See Also: + +[`Option::ok_or`][okor], [Result::map_err][maperr] + +[okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or +[maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err diff --git a/examples/error/option_with_result/multiple_error_types.rs b/examples/error/option_with_result/multiple_error_types.rs new file mode 100644 index 0000000000..2a5d0a679c --- /dev/null +++ b/examples/error/option_with_result/multiple_error_types.rs @@ -0,0 +1,30 @@ +// Use `String` as our error type +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + .ok_or("Please use a vector with at least one element.".to_owned()) + .and_then(|s| s.parse::() + // Map the errors `parse` yields to `String`. + .map_err(|e| e.to_string()) + // `Result` is the new return type, + // and we can now double the number inside. + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(empty)); + print(double_first(strings)); +} \ No newline at end of file diff --git a/examples/structure.json b/examples/structure.json index 8be0748c13..a54df0d462 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -148,8 +148,8 @@ { "id": "result", "title": "Result", "children": [ { "id": "result_map", "title": "map for Result", "children": null }, { "id": "result_alias", "title": "aliases for Result", "children": null } - ] }, - { "id": "option_with_result", "title": "Options with Results", "children": [ + ] }, + { "id": "multiple_error_types", "title": "Multiple error types", "children": [ { "id": "result_string_errors", "title": "Strings as errors", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, { "id": "enter_try", "title": "try!", "children": null } From 00aba53c1d4f69bee8ec12b701cda228c92ab28f Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:01:38 -0700 Subject: [PATCH 0537/1122] Renamed rethink.rs to reenabling_box.rs Renamed to match structure.json --- examples/error/reenabling_box/input.md | 2 +- examples/error/reenabling_box/{rethink.rs => reenabling_box.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename examples/error/reenabling_box/{rethink.rs => reenabling_box.rs} (100%) diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md index ed826e6c43..78073af443 100644 --- a/examples/error/reenabling_box/input.md +++ b/examples/error/reenabling_box/input.md @@ -32,7 +32,7 @@ trait Error: Debug + Display { By implementing this, our previous example would be just as valid when the error type is `Box` as it was before with `DoubleError`. -{rethink.play} +{reenabling_box.play} ### See also: diff --git a/examples/error/reenabling_box/rethink.rs b/examples/error/reenabling_box/reenabling_box.rs similarity index 100% rename from examples/error/reenabling_box/rethink.rs rename to examples/error/reenabling_box/reenabling_box.rs From d368dbe69c1f1cea070a9521013ffabe2f9e6897 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 16:02:42 -0700 Subject: [PATCH 0538/1122] Renamed folder for 16.5 option_with_result -> multiple_error_types Now matches structure.json --- .../combinator_combinations/input.md | 0 .../combinator_combinations/result_try.rs | 0 .../enter_try/input.md | 0 .../{option_with_result => multiple_error_types}/enter_try/try.rs | 0 .../error/{option_with_result => multiple_error_types}/input.md | 0 .../multiple_error_types.rs | 0 .../result_string_errors/input.md | 0 .../result_string_errors/result_string.rs | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename examples/error/{option_with_result => multiple_error_types}/combinator_combinations/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/combinator_combinations/result_try.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/enter_try/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/enter_try/try.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/multiple_error_types.rs (100%) rename examples/error/{option_with_result => multiple_error_types}/result_string_errors/input.md (100%) rename examples/error/{option_with_result => multiple_error_types}/result_string_errors/result_string.rs (100%) diff --git a/examples/error/option_with_result/combinator_combinations/input.md b/examples/error/multiple_error_types/combinator_combinations/input.md similarity index 100% rename from examples/error/option_with_result/combinator_combinations/input.md rename to examples/error/multiple_error_types/combinator_combinations/input.md diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/multiple_error_types/combinator_combinations/result_try.rs similarity index 100% rename from examples/error/option_with_result/combinator_combinations/result_try.rs rename to examples/error/multiple_error_types/combinator_combinations/result_try.rs diff --git a/examples/error/option_with_result/enter_try/input.md b/examples/error/multiple_error_types/enter_try/input.md similarity index 100% rename from examples/error/option_with_result/enter_try/input.md rename to examples/error/multiple_error_types/enter_try/input.md diff --git a/examples/error/option_with_result/enter_try/try.rs b/examples/error/multiple_error_types/enter_try/try.rs similarity index 100% rename from examples/error/option_with_result/enter_try/try.rs rename to examples/error/multiple_error_types/enter_try/try.rs diff --git a/examples/error/option_with_result/input.md b/examples/error/multiple_error_types/input.md similarity index 100% rename from examples/error/option_with_result/input.md rename to examples/error/multiple_error_types/input.md diff --git a/examples/error/option_with_result/multiple_error_types.rs b/examples/error/multiple_error_types/multiple_error_types.rs similarity index 100% rename from examples/error/option_with_result/multiple_error_types.rs rename to examples/error/multiple_error_types/multiple_error_types.rs diff --git a/examples/error/option_with_result/result_string_errors/input.md b/examples/error/multiple_error_types/result_string_errors/input.md similarity index 100% rename from examples/error/option_with_result/result_string_errors/input.md rename to examples/error/multiple_error_types/result_string_errors/input.md diff --git a/examples/error/option_with_result/result_string_errors/result_string.rs b/examples/error/multiple_error_types/result_string_errors/result_string.rs similarity index 100% rename from examples/error/option_with_result/result_string_errors/result_string.rs rename to examples/error/multiple_error_types/result_string_errors/result_string.rs From 48037d24cc431d0ba1b0837d80733a5d7ea85371 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 17:58:40 -0700 Subject: [PATCH 0539/1122] Updated multiple_error_types (input.md) Rewording for better transitions --- examples/error/multiple_error_types/input.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/error/multiple_error_types/input.md b/examples/error/multiple_error_types/input.md index 9201d57429..872c4220b8 100644 --- a/examples/error/multiple_error_types/input.md +++ b/examples/error/multiple_error_types/input.md @@ -1,9 +1,10 @@ The previous examples have always been very convenient; `Result`s interact with other `Result`s and `Option`s interact with other `Option`s. -Sometimes an `Option` needs to interact with a `Result`, or a `Result` -needs to interact with a `Result`. In those cases, we want to -handle the *composition of distinct error types*. +Sometimes an `Option` needs to interact with a `Result`, or a +`Result` needs to interact with a `Result`. In those +cases, we want to manage our different error types in a way that makes them +composable and easy to interact with. In the following code, two instances of `unwrap` generate different error types. `Vec::first` returns an `Option`, while `parse::` returns a @@ -27,12 +28,17 @@ fn main() { } ``` -Using our knowledge of combinators, we can rewrite the above to explicitly -handle errors. In doing so, we convert both `Option`s and `Result`s into -`Result`s, and map them to the same error type (`String`): +Using our knowledge of combinators, we can rewrite the above to explicitly +handle errors. Since two different types of errors can occur, we need to +convert them to a common type such as a `String`. + +To do so, we convert both the `Option` and `Result` into `Result`s, and +then map their errors to the same type: {multiple_error_types.play} +In the next section, we'll see an alternate method of explicitly handling these errors. + ### See Also: [`Option::ok_or`][okor], [Result::map_err][maperr] From ef56590c8c844681c42d8776eaaab7da8053fb16 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 18:01:22 -0700 Subject: [PATCH 0540/1122] Removed "Strings as errors" chapter, Renamed result_try to early_returns Updated structure.json to reflect removal/renaming +Very minor change to multiple_error_types.rs --- .../result_try.rs => early_returns/early_returns.rs} | 0 .../{combinator_combinations => early_returns}/input.md | 0 examples/error/multiple_error_types/multiple_error_types.rs | 2 +- examples/structure.json | 3 +-- 4 files changed, 2 insertions(+), 3 deletions(-) rename examples/error/multiple_error_types/{combinator_combinations/result_try.rs => early_returns/early_returns.rs} (100%) rename examples/error/multiple_error_types/{combinator_combinations => early_returns}/input.md (100%) diff --git a/examples/error/multiple_error_types/combinator_combinations/result_try.rs b/examples/error/multiple_error_types/early_returns/early_returns.rs similarity index 100% rename from examples/error/multiple_error_types/combinator_combinations/result_try.rs rename to examples/error/multiple_error_types/early_returns/early_returns.rs diff --git a/examples/error/multiple_error_types/combinator_combinations/input.md b/examples/error/multiple_error_types/early_returns/input.md similarity index 100% rename from examples/error/multiple_error_types/combinator_combinations/input.md rename to examples/error/multiple_error_types/early_returns/input.md diff --git a/examples/error/multiple_error_types/multiple_error_types.rs b/examples/error/multiple_error_types/multiple_error_types.rs index 2a5d0a679c..bcc909a069 100644 --- a/examples/error/multiple_error_types/multiple_error_types.rs +++ b/examples/error/multiple_error_types/multiple_error_types.rs @@ -7,7 +7,7 @@ fn double_first(vec: Vec<&str>) -> Result { // Otherwise, provide an `Err` containing this `String`. .ok_or("Please use a vector with at least one element.".to_owned()) .and_then(|s| s.parse::() - // Map the errors `parse` yields to `String`. + // Map any errors that `parse` yields to `String`. .map_err(|e| e.to_string()) // `Result` is the new return type, // and we can now double the number inside. diff --git a/examples/structure.json b/examples/structure.json index a54df0d462..05e354431a 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -150,8 +150,7 @@ { "id": "result_alias", "title": "aliases for Result", "children": null } ] }, { "id": "multiple_error_types", "title": "Multiple error types", "children": [ - { "id": "result_string_errors", "title": "Strings as errors", "children": null }, - { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, + { "id": "early_returns", "title": "Early returns", "children": null }, { "id": "enter_try", "title": "try!", "children": null } ] }, { "id": "define_error_type", "title": "Defining an error type", "children": null }, From ce09390bb8fd0ff032adb0f0e29c8e22705c5da4 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 28 Jul 2016 18:21:20 -0700 Subject: [PATCH 0541/1122] Update input.md (early_returns) New text in its entirety, with inspiration from https://doc.rust-lang.org/book/error-handling.html#early-returns The .rs file will include a rewritten version of the "Multiple error types" example. --- .../early_returns/input.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/input.md b/examples/error/multiple_error_types/early_returns/input.md index b7d1cb76c0..bb61a12182 100644 --- a/examples/error/multiple_error_types/early_returns/input.md +++ b/examples/error/multiple_error_types/early_returns/input.md @@ -1,15 +1,15 @@ -What if multiple `Results` needed to interact together? Is it still reasonably convenient? -It turns out, not really. +In the previous example, we explicitly handled the errors using combinators. +Another way to deal with this case analysis is to use a combination of +`match` statements and *early returns*. -{result_try.play} +That is, we can simply stop executing the function and return the error if +one occurs. For some, this form of code can be easier to both read and +write. Consider this version of the previous example, rewritten using early returns: -What is happening is this approach tries to work with the data without ever removing the `Ok` -wrapper on it. Sometimes it is a good approach but in this case it is really awkward. What if -we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. +{early_returns.play} -### See also: +At this point, we've learned to explicitly handle errors using combinators +and early returns. While we generally want to avoid panicking, always +handling errors explicitly is cumbersome. -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +So what if we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. From 6747509cd3cecf34c32c7896a34b059824f5d316 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 15:05:38 -0700 Subject: [PATCH 0542/1122] Minor rewording in `early_returns` --- examples/error/multiple_error_types/early_returns/input.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/input.md b/examples/error/multiple_error_types/early_returns/input.md index bb61a12182..61f94e3c7f 100644 --- a/examples/error/multiple_error_types/early_returns/input.md +++ b/examples/error/multiple_error_types/early_returns/input.md @@ -9,7 +9,8 @@ write. Consider this version of the previous example, rewritten using early retu {early_returns.play} At this point, we've learned to explicitly handle errors using combinators -and early returns. While we generally want to avoid panicking, always -handling errors explicitly is cumbersome. +and early returns. While we generally want to avoid panicking, explicitly +handling all of our errors is cumbersome. -So what if we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. +In the next section, we'll introduce `try!` for the cases where we simply +need to `unwrap` without possibly inducing `panic`. From a6bd6bc883b30a436bc4b3803f900572c6192319 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:25:00 -0700 Subject: [PATCH 0543/1122] Rename reenabling_box and added `` to some other sections Renamed reenabling_box to `Box`ing errors Added `` to other chapter sections for consistency. Added `` to `Box`ing errors section for consistency. --- .../boxing_errors.rs} | 0 examples/error/boxing_errors/input.md | 43 +++++++++++++++++++ examples/error/reenabling_box/input.md | 42 ------------------ examples/structure.json | 20 ++++----- 4 files changed, 53 insertions(+), 52 deletions(-) rename examples/error/{reenabling_box/reenabling_box.rs => boxing_errors/boxing_errors.rs} (100%) create mode 100644 examples/error/boxing_errors/input.md delete mode 100644 examples/error/reenabling_box/input.md diff --git a/examples/error/reenabling_box/reenabling_box.rs b/examples/error/boxing_errors/boxing_errors.rs similarity index 100% rename from examples/error/reenabling_box/reenabling_box.rs rename to examples/error/boxing_errors/boxing_errors.rs diff --git a/examples/error/boxing_errors/input.md b/examples/error/boxing_errors/input.md new file mode 100644 index 0000000000..d8136f25ad --- /dev/null +++ b/examples/error/boxing_errors/input.md @@ -0,0 +1,43 @@ +By implementing `Display` and `From` for our error type, we enabled +almost all of the `std` library error handling tools. However, we missed +something: the ability to easily `Box` our error type. + +The `std` library automatically converts any type that implements the +`Error` trait into the trait object `Box`, via `From`. To a +library user, this conveniently allows the following: + +```rust +fn foo(...) -> Result> { ... } +``` + +A user may use any variety of external libraries which each provide their own error +types. In order to define a valid `Result` type, the user has a few choices: + +* define a new wrapper error type around the library's error types +* convert the error types to `String` or another intermediate choice +* `Box` the error types into `Box` via type erasure + +"Boxing" the error type is a common choice. The drawback is that the +underlying error type is only known at runtime and not +[statically determined][dynamic_dispatch]. As mentioned above, all that +needs to be done is to implement the `Error` trait: + +```rust +trait Error: Debug + Display { + fn description(&self) -> &str; + fn cause(&self) -> Option<&Error>; +} +``` + +With this implementation, let's look at our most recent example. Note that +it is just as valid with the error type of `Box` as it was before +with `DoubleError`: + +{boxing_errors.play} + +### See also: + +[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] + +[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch +[error]: http://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md deleted file mode 100644 index 78073af443..0000000000 --- a/examples/error/reenabling_box/input.md +++ /dev/null @@ -1,42 +0,0 @@ -We have seen that by implementing `Display` and `From` for our error type, we have enabled -usage of almost all of the std library error handling tools. That is, we missed one -capability: the ability to easily `box` our error type. - -Namely, the std library will automatically convert from any type which implements the -`Error` trait into the trait object `Box` via `From`. To a library user, this -conveniently allows the following: - -```rust -// Any error type automatically convertible to `Box` may be used here. -fn foo(...) -> Result> { ... } -``` - -For example, a user may use a variety of libraries which each provide their own error -types. In order to define a valid `Result` type, the user has a few choices: - -* define a new wrapper error type around the external libraries error types -* convert it to `String` or some other intermediate choice -* box it up into `Box` via type erasure - -Boxing it is a common choice. The only penalty is that the underlying error type is only known -at runtime and not [statically determined][dynamic_dispatch]. All that needs to be done to enable -this is implement the `Error` trait: - -```rust -trait Error: Debug + Display { - fn description(&self) -> &str; - fn cause(&self) -> Option<&Error>; -} -``` - -By implementing this, our previous example would be just as valid when the error type -is `Box` as it was before with `DoubleError`. - -{reenabling_box.play} - -### See also: - -[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] - -[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch -[error]: http://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/structure.json b/examples/structure.json index 05e354431a..cb8c4d9f02 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -140,22 +140,22 @@ { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "error", "title": "Error handling", "children": [ - { "id": "panic", "title": "panic", "children": null }, - { "id": "option_unwrap", "title": "Option & unwrap", "children": [ - { "id": "map", "title": "Combinators: map", "children": null }, - { "id": "and_then", "title": "Combinators: and_then", "children": null }, + { "id": "panic", "title": "`panic`", "children": null }, + { "id": "option_unwrap", "title": "`Option` & `unwrap`", "children": [ + { "id": "map", "title": "Combinators: `map`", "children": null }, + { "id": "and_then", "title": "Combinators: `and_then`", "children": null }, ] }, - { "id": "result", "title": "Result", "children": [ - { "id": "result_map", "title": "map for Result", "children": null }, - { "id": "result_alias", "title": "aliases for Result", "children": null } + { "id": "result", "title": "`Result`", "children": [ + { "id": "result_map", "title": "`map` for `Result`", "children": null }, + { "id": "result_alias", "title": "aliases for `Result`", "children": null } ] }, { "id": "multiple_error_types", "title": "Multiple error types", "children": [ { "id": "early_returns", "title": "Early returns", "children": null }, - { "id": "enter_try", "title": "try!", "children": null } + { "id": "enter_try", "title": "Introducing `try!`", "children": null } ] }, { "id": "define_error_type", "title": "Defining an error type", "children": null }, - { "id": "reenter_try", "title": "Other uses of try!", "children": null }, - { "id": "reenabling_box", "title": "Re-enabling box", "children": null } + { "id": "reenter_try", "title": "Other uses of `try!`", "children": null }, + { "id": "boxing_errors", "title": "`Box`ing errors", "children": null } ] }, { "id": "std", "title": "Std library types", "children": [ { "id": "box", "title": "Box, stack and heap", "children": null }, From 827254dbf63f8dce5f4d52291ed6e03290b13ad4 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:25:47 -0700 Subject: [PATCH 0544/1122] Reworked example as per minor discussion in #764 Shoutouts to @mdinger for doing the heavy lifting here --- .../early_returns/early_returns.rs | 68 +++++++------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/examples/error/multiple_error_types/early_returns/early_returns.rs b/examples/error/multiple_error_types/early_returns/early_returns.rs index 433699b917..b8ce1a450d 100644 --- a/examples/error/multiple_error_types/early_returns/early_returns.rs +++ b/examples/error/multiple_error_types/early_returns/early_returns.rs @@ -1,51 +1,33 @@ -use std::io::prelude::*; -use std::fs::File; - +// Use `String` as our error type type Result = std::result::Result; -// Setup to make this work. Create two files with some info. Ignore the -// return values because we don't care about them here. -fn setup() { - File::create("a") - .and_then(|mut file| file.write_all(b"grape")) - .unwrap(); - - File::create("b") - .and_then(|mut file| file.write_all(b"fruit")) - .unwrap(); -} - -// Get the data from each file with the data stored in a `Result`. -fn get_data(path: &str) -> Result { - File::open(path) - .map_err(|err| err.to_string()) - .and_then(|mut file| { - let mut contents = String::new(); - - // Read the data into `contents`. - file.read_to_string(&mut contents) - .map_err(|err| err.to_string()) - // Ignore the output `read_to_string` returns and return `contents`. - .map(|_| contents) - }) +fn double_first(vec: Vec<&str>) -> Result { + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + let first = match vec.first() { + Some(first) => first, + None => return Err("Please use a vector with at least one element.".to_owned()) + }; + + // Double the number inside if `parse` works fine. + // Otherwise, map any errors that `parse` yields to `String`. + match first.parse::() { + Ok(i) => Ok(2 * i), + Err(e) => Err(e.to_string()), + } } -// Concat the contents of the two files together into a new `Result`. -fn concat(filename_a: &str, filename_b: &str) -> Result { - let (data_a, data_b) = (get_data(filename_a), get_data(filename_b)); - - data_a.and_then(|a| - // Return `Ok` when both `a` and `b` are `Ok`. Otherwise return - // whichever has the first `Err`. - data_b.and_then(|b| Ok(a + &b)) - ) +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } } fn main() { - setup(); + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; - match concat("a", "b") { - Ok(n) => println!("{}", n), - Err(e) => println!("Error: {}", e), - } -} + print(double_first(empty)); + print(double_first(strings)); +} \ No newline at end of file From 739d2071285b2e78bb469ed34725e82c86d111ec Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 8 Sep 2016 18:29:23 -0700 Subject: [PATCH 0545/1122] Removed working section `result_string_errors` Contained information is now redundant with `multiple_error_types` --- .../result_string_errors/input.md | 11 ------- .../result_string_errors/result_string.rs | 33 ------------------- 2 files changed, 44 deletions(-) delete mode 100644 examples/error/multiple_error_types/result_string_errors/input.md delete mode 100644 examples/error/multiple_error_types/result_string_errors/result_string.rs diff --git a/examples/error/multiple_error_types/result_string_errors/input.md b/examples/error/multiple_error_types/result_string_errors/input.md deleted file mode 100644 index e2a6de3d3d..0000000000 --- a/examples/error/multiple_error_types/result_string_errors/input.md +++ /dev/null @@ -1,11 +0,0 @@ -From our previous example, one method of solving our issue with `unwrap` is to remove it. -In doing so, we must move from implicit to explicit error handling. Since the only -types in play are `Option` and `Result`, we can consider converting both into -`Result`s with the same `Err` type. For our first attempt at this solution, -let's try using a `String` for our error: - -{result_string.play} - -This is not too bad, but it is hardly as nice as the original (it can still be nicer but -we are not there yet). Unfortunately, this approach scales poorly with increasing -numbers of `Result`s, as will be seen in the next example. diff --git a/examples/error/multiple_error_types/result_string_errors/result_string.rs b/examples/error/multiple_error_types/result_string_errors/result_string.rs deleted file mode 100644 index abda6a654f..0000000000 --- a/examples/error/multiple_error_types/result_string_errors/result_string.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - vec.first() - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - .ok_or("Please use a vector with at least one element.".to_owned()) - // Recall that `parse` returns a `Result`. - .and_then(|s| s.parse::() - // Map the errors `parse` yields to `String`. - // The return type is then `Result`. - .map_err(|e| e.to_string()) - // At this point, we can double the number inside. - .map(|i| 2 * i)) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(numbers)); - print(double_first(empty)); - print(double_first(strings)); -} From 922ebc215b3cbcbb5100234c38ee3f96966e8026 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Sat, 10 Sep 2016 12:29:49 -0700 Subject: [PATCH 0546/1122] Typo fix to structure.json; minor rewording/style changes via @mdinger comments --- examples/error/input.md | 10 +++++----- examples/error/multiple_error_types/input.md | 2 +- examples/error/result/input.md | 2 +- examples/error/result/result_map/input.md | 3 ++- examples/structure.json | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/error/input.md b/examples/error/input.md index 46175a4393..679f1c84cb 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -1,9 +1,9 @@ Error handling is the process of handling the possibility of failure. For example, failing to read a file and then continuing to use that *bad* input -would clearly be problematic. Noticing and managing those errors in an -explicit fashion saves the rest of the program from potential issues. +would clearly be problematic. Noticing and explicitly managing those errors +saves the rest of the program from various pitfalls. -For additional information on error handling, see the section on error -handling in the [official book][book]. +For a more rigorous discussion of error handling, refer to the error +handling section in the [official book][book]. -[book]: https://doc.rust-lang.org/book/error-handling.html \ No newline at end of file +[book]: https://doc.rust-lang.org/book/error-handling.html diff --git a/examples/error/multiple_error_types/input.md b/examples/error/multiple_error_types/input.md index 872c4220b8..b879d8cc0d 100644 --- a/examples/error/multiple_error_types/input.md +++ b/examples/error/multiple_error_types/input.md @@ -41,7 +41,7 @@ In the next section, we'll see an alternate method of explicitly handling these ### See Also: -[`Option::ok_or`][okor], [Result::map_err][maperr] +[`Option::ok_or`][okor], [`Result::map_err`][maperr] [okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or [maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err diff --git a/examples/error/result/input.md b/examples/error/result/input.md index 13072316b8..d36fc16134 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -6,7 +6,7 @@ That is, `Result` could have one of two outcomes: * `Ok`: An element `T` was found * `Err`: An error was found with element `E` -By convention, the expected outcome is “Ok” while the unexpected outcome is “Err”. +By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`. Like `Option`, `Result` has many methods associated with it. `unwrap()`, for example, either yields the element `T` or `panic`s. For case handling, diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md index 0c4214ad13..9dd704b82b 100644 --- a/examples/error/result/result_map/input.md +++ b/examples/error/result/result_map/input.md @@ -3,7 +3,7 @@ To avoid that, we need to be more specific about the return type. There, the regular element is of type `i32`. To determine the `Err` type, we look to -`parse()`, which is implemented with the [`FromStr`][from_str] trait for +[`parse()`](parse), which is implemented with the [`FromStr`][from_str] trait for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. In the example below, the straightforward `match` statement leads to code @@ -13,6 +13,7 @@ contains a complete listing. {result_map.play} +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse [from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html [i32]: http://doc.rust-lang.org/std/primitive.i32.html [parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html diff --git a/examples/structure.json b/examples/structure.json index cb8c4d9f02..290107d6dd 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -143,7 +143,7 @@ { "id": "panic", "title": "`panic`", "children": null }, { "id": "option_unwrap", "title": "`Option` & `unwrap`", "children": [ { "id": "map", "title": "Combinators: `map`", "children": null }, - { "id": "and_then", "title": "Combinators: `and_then`", "children": null }, + { "id": "and_then", "title": "Combinators: `and_then`", "children": null } ] }, { "id": "result", "title": "`Result`", "children": [ { "id": "result_map", "title": "`map` for `Result`", "children": null }, From 85fa6d810b5db211a8b6168a0f97d4c684c07ead Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Sat, 10 Sep 2016 12:52:04 -0700 Subject: [PATCH 0547/1122] Added a period --- examples/error/reenter_try/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index e298ba910d..822940a04f 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -17,7 +17,7 @@ This is only mostly true. It actually means `unwrap` or between different types, this means that if you `try!` where the error is convertible to the return type, it will convert automatically. -Here, we rewrite the previous example using `try!` As a result, the +Here, we rewrite the previous example using `try!`. As a result, the `map_err` will go away when `From::from` is implemented for our error type: {reenter_try.play} From 2eaeebb379ec5e1f2d80dbf9fa337ab906376d85 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 12 Sep 2016 18:14:08 -0700 Subject: [PATCH 0548/1122] Replaced `enter_try` code example; reworded text to match Code example provided by @mdinger Text updated in `enter_try` and `define_error_type` --- examples/error/define_error_type/input.md | 12 ++-- .../multiple_error_types/enter_try/input.md | 20 ++++--- .../multiple_error_types/enter_try/try.rs | 56 ++++++------------- 3 files changed, 34 insertions(+), 54 deletions(-) diff --git a/examples/error/define_error_type/input.md b/examples/error/define_error_type/input.md index 0b51ad74dc..f8e49b158c 100644 --- a/examples/error/define_error_type/input.md +++ b/examples/error/define_error_type/input.md @@ -1,7 +1,4 @@ -Rust allows us to define our own error types. Up until now, we've been using -`String`s as errors. However, they are somewhat limiting as an error type. - -In general, a "good" error type: +Rust allows us to define our own error types. In general, a "good" error type: * Represents different errors with the same type * Presents nice error messages to the user @@ -12,9 +9,10 @@ In general, a "good" error type: - Good: `Err(BadChar(c, position))` - Bad: `Err("+ cannot be used here".to_owned())` -Note that a `String` fulfills the first two criteria, but not the last two. -This makes `String` errors verbose to create and difficult to react to. -It should not be necessary to pollute logic heavy code with `String` formatting simply to display nicely. +Note that a `String` (which we've been using up to this point) fulfills the +first two criteria, but not the last two. This makes `String` errors verbose +to create and difficult to react to. It should not be necessary to pollute +logic heavy code with `String` formatting simply to display nicely. {define_error_type.play} diff --git a/examples/error/multiple_error_types/enter_try/input.md b/examples/error/multiple_error_types/enter_try/input.md index d1567430b3..76a46b01cc 100644 --- a/examples/error/multiple_error_types/enter_try/input.md +++ b/examples/error/multiple_error_types/enter_try/input.md @@ -1,19 +1,21 @@ -The previous problem was awkward because avoiding `unwrap` forced us to nest deeper and -deeper when what we really wanted was to get the variable *out*. So, is there any way -to accomodate this approach without `panic`? Well, what is a valid action to take when -an `Err` is found? It turns out there are two: +Sometimes we just want the simplicity of `unwrap` without the possibility of +a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when +what we really wanted was to get the variable *out*. This is exactly the purpose of `try!`. + +Upon finding an `Err`, there are two valid actions to take: 1. `panic!` which we already decided to try to avoid if possible 2. `return` because an `Err` means it cannot be handled -This is exactly the purpose of `try!`; it is *almost*[^1] exactly equivalent to an -`unwrap` which `returns` instead of `panics` on `Errs`. +`try!` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s +instead of `panic`s on `Err`s. Let's see how we can simplify the earlier +example that used combinators: {try.play} -This really is a *huge* improvement but there is still the nagging issue of `map_err`. There is -actually a way to avoid it (we are using it everywhere it seems) but we are still missing some -details. First, we have to learn how to make better errors. +Note that up until now, we've been using `String`s as errors. However, they +are somewhat limiting as an error type. In the next section, we'll learn how +to make more structured and informative errors by defining their types. [^1]: See [re-enter try!][re_enter_try] for more details. diff --git a/examples/error/multiple_error_types/enter_try/try.rs b/examples/error/multiple_error_types/enter_try/try.rs index 394a21c530..5a3337bd03 100644 --- a/examples/error/multiple_error_types/enter_try/try.rs +++ b/examples/error/multiple_error_types/enter_try/try.rs @@ -1,47 +1,27 @@ -use std::io::prelude::*; -use std::fs::File; - +// Use `String` as our error type type Result = std::result::Result; -// Setup to make this work. Create two files with some info. -fn setup() -> std::io::Result<()> { - let mut a = try!(File::create("a")); - try!(a.write_all(b"grape")); - - let mut b = try!(File::create("b")); - b.write_all(b"fruit") -} - -// Get the data from each file with the data stored in a `Result`. -fn get_data(path: &str) -> Result { - // `try` unwraps the value or returns the error. - let mut file = try!(File::open(path) - // Errors still must be converted to strings. - .map_err(|err| err.to_string()) - ); - let mut contents = String::new(); - - // Read the data into `contents`. - try!(file.read_to_string(&mut contents) - .map_err(|err| err.to_string()) - ); - - Ok(contents) +fn double_first(vec: Vec<&str>) -> Result { + let first = try!(vec.first() + .ok_or("Please use a vector with at least one element.".to_owned())); + + let value = try!(first.parse::() + .map_err(|e| e.to_string())); + + Ok(2 * value) } -// Concat the contents of the two files together into a new `Result`. -fn concat(a: &str, b: &str) -> Result { - let (data_a, data_b) = (try!(get_data(a)), try!(get_data(b))); - - Ok(data_a + &data_b) +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } } fn main() { - // Ignore this result. - setup().unwrap(); + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; - match concat("a", "b") { - Ok(n) => println!("{}", n), - Err(e) => println!("Error: {}", e), - } + print(double_first(empty)); + print(double_first(strings)); } From 42c111b03dde30961536d44172428ed68d876a96 Mon Sep 17 00:00:00 2001 From: Alaric Nightingale Date: Wed, 21 Sep 2016 02:20:28 +0100 Subject: [PATCH 0549/1122] generics/assoc_items/types: Fix typo in comment --- examples/generics/assoc_items/types/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/assoc_items/types/types.rs b/examples/generics/assoc_items/types/types.rs index d6ae8f3e95..e3f9d9638e 100644 --- a/examples/generics/assoc_items/types/types.rs +++ b/examples/generics/assoc_items/types/types.rs @@ -19,7 +19,7 @@ impl Contains for Container { type A = i32; type B = i32; - // `&Self::A` and `&self::B` are also valid here. + // `&Self::A` and `&Self::B` are also valid here. fn contains(&self, number_1: &i32, number_2: &i32) -> bool { (&self.0 == number_1) && (&self.1 == number_2) } From eeac87f5ff0020dfb47bbfde4d74a73870764024 Mon Sep 17 00:00:00 2001 From: Augustin Trancart Date: Thu, 22 Sep 2016 18:33:35 +0200 Subject: [PATCH 0550/1122] closures/output_parameters: fix typo --- examples/fn/closures/output_parameters/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index 200adb49c7..6e03da3ddd 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -1,4 +1,4 @@ -Using closures as input parameters are possible, so returning closures as +Closures as input parameters are possible, so returning closures as output parameters should also be possible. However, returning closure types are problematic because Rust currently only supports returning concrete (non-generic) types. Anonymous closure types are, by definition, unknown From 7d5c00ce44e43c386f43682e261171ec2efbcb21 Mon Sep 17 00:00:00 2001 From: francozappa Date: Mon, 3 Oct 2016 10:56:20 +0800 Subject: [PATCH 0551/1122] More info in Length doc and final printed messages --- examples/generics/phantom/testcase_units/units.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index c23249d809..18be5e9aba 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -7,11 +7,12 @@ enum Inch {} #[derive(Debug, Clone, Copy)] enum Mm {} -/// `Length` is a type with phantom type parameter `Unit`. +/// `Length` is a type with phantom type parameter `Unit`, +/// and is not generic over the length type (that is `f64`). /// /// `f64` already implements the `Clone` and `Copy` traits. #[derive(Debug, Clone, Copy)] -struct Length(f64,PhantomData); +struct Length(f64, PhantomData); /// The `Add` trait defines the behavior of the `+` operator. impl Add for Length { @@ -38,8 +39,8 @@ fn main() { let two_meters = one_meter + one_meter; // Addition works. - println!("one foot + one_foot = {:?}", two_feet); - println!("one meter + one_meter = {:?}", two_meters); + println!("one foot + one_foot = {:?} in", two_feet.0); + println!("one meter + one_meter = {:?} mm", two_meters.0); // Nonsensical operations fail as they should: // Compile-time Error: type mismatch. From cb46597f4039f62a05b126b749e0ce14695bbb90 Mon Sep 17 00:00:00 2001 From: francozappa Date: Wed, 5 Oct 2016 08:26:13 +0800 Subject: [PATCH 0552/1122] More emphasis on the type system --- examples/scope/borrow/borrow.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/examples/scope/borrow/borrow.rs b/examples/scope/borrow/borrow.rs index 5f52585f6a..53179805b7 100644 --- a/examples/scope/borrow/borrow.rs +++ b/examples/scope/borrow/borrow.rs @@ -1,34 +1,35 @@ -// This function takes ownership of a box and destroys it -fn eat_box(boxed_int: Box) { - println!("Destroying box that contains {}", boxed_int); +// This function takes ownership of a box and destroys it +fn eat_box_i32(boxed_i32: Box) { + println!("Destroying box that contains {}", boxed_i32); } // This function borrows an i32 -fn borrow_box(borrowed_int: &i32) { - println!("This int is: {}", borrowed_int); +fn borrow_i32(borrowed_i32: &i32) { + println!("This int is: {}", borrowed_i32); } fn main() { - // Create a boxed integer - let boxed_int = Box::new(5); + // Create a boxed i32, and a stacked i32 + let boxed_i32 = Box::new(5_i32); + let stacked_i32 = 6_i32; // Borrow the contents of the box. Ownership is not taken, // so the contents can be borrowed again. - borrow_box(&boxed_int); - borrow_box(&boxed_int); + borrow_i32(&boxed_i32); + borrow_i32(&stacked_i32); { // Take a reference to the data contained inside the box - let _ref_to_int: &i32 = &boxed_int; + let _ref_to_i32: &i32 = &boxed_i32; - // Error! - // Can't destroy `boxed_int` while the inner value is borrowed. - eat_box(boxed_int); + // Error! + // Can't destroy `boxed_i32` while the inner value is borrowed. + eat_box_i32(boxed_i32); // FIXME ^ Comment out this line - // `_ref_to_int` goes out of scope and is no longer borrowed. + // `_ref_to_i32` goes out of scope and is no longer borrowed. } - // Box can now give up ownership to `eat_box` and be destroyed - eat_box(boxed_int); + // `boxed_i32` can now give up ownership to `eat_box` and be destroyed + eat_box_i32(boxed_i32); } From f8e24e8e0d40d168d24fb2e250d8a6a05ccb99fe Mon Sep 17 00:00:00 2001 From: francozappa Date: Thu, 6 Oct 2016 08:23:26 +0800 Subject: [PATCH 0553/1122] Clarify single mutable reference vs mutliple references --- examples/scope/borrow/alias/alias.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/scope/borrow/alias/alias.rs b/examples/scope/borrow/alias/alias.rs index b3bb86f2cf..5776e1fe24 100644 --- a/examples/scope/borrow/alias/alias.rs +++ b/examples/scope/borrow/alias/alias.rs @@ -36,10 +36,15 @@ fn main() { //println!("Point Z coordinate is {}", point.z); // TODO ^ Try uncommenting this line + // Ok! Mutable references can be passed as immutable to `println!` + println!("Point has coordinates: ({}, {}, {})", + mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); + // Mutable reference goes out of scope } // Immutable references to point are allowed again + let borrowed_point = &point; println!("Point now has coordinates: ({}, {}, {})", - point.x, point.y, point.z); + borrowed_point.x, borrowed_point.y, borrowed_point.z); } From 11d4887c8119bc2cb10cac88418afcd02f4a3ec6 Mon Sep 17 00:00:00 2001 From: francozappa Date: Fri, 7 Oct 2016 07:42:18 +0800 Subject: [PATCH 0554/1122] Explicit add_one return value --- examples/scope/lifetime/methods/methods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/methods/methods.rs b/examples/scope/lifetime/methods/methods.rs index 9733c69b1a..95915b3c6c 100644 --- a/examples/scope/lifetime/methods/methods.rs +++ b/examples/scope/lifetime/methods/methods.rs @@ -2,7 +2,7 @@ struct Owner(i32); impl Owner { // Annotate lifetimes as in a standalone function. - fn add_one<'a>(&'a mut self) { self.0 += 1 } + fn add_one<'a>(&'a mut self) { self.0 += 1; } fn print<'a>(&'a self) { println!("`print`: {}", self.0); } From 76f1ebde50c90037055579b76645a5f477370f20 Mon Sep 17 00:00:00 2001 From: francozappa Date: Mon, 10 Oct 2016 11:03:42 +0800 Subject: [PATCH 0555/1122] Remove print() closure See next example --- examples/fn/closures/closures.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/fn/closures/closures.rs b/examples/fn/closures/closures.rs index 6f49304958..af8d2d4c18 100644 --- a/examples/fn/closures/closures.rs +++ b/examples/fn/closures/closures.rs @@ -19,14 +19,4 @@ fn main() { let one = || 1; println!("closure returning one: {}", one()); - // It is possible to capture variables from the enclosing - // environment; something which is impossible with functions. - let professor_x = "Charles Xavier"; - - // A closure which takes no argument, returning nothing, prints - // a variable from the enclosing scope. - let print = || println!("Professor X's name is: {}", professor_x); - - // Call the closure. - print(); } From 2c05e1e8df3e862714b07b450e93bd4ad01d2fbf Mon Sep 17 00:00:00 2001 From: francozappa Date: Mon, 10 Oct 2016 11:06:56 +0800 Subject: [PATCH 0556/1122] Minor string fixes --- examples/fn/closures/closures.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fn/closures/closures.rs b/examples/fn/closures/closures.rs index af8d2d4c18..82002ff427 100644 --- a/examples/fn/closures/closures.rs +++ b/examples/fn/closures/closures.rs @@ -11,8 +11,8 @@ fn main() { let i = 1; // Call the function and closures. println!("function: {}", function(i)); - println!("annotated closure: {}", closure_annotated(i)); - println!("inferred closure: {}", closure_inferred(i)); + println!("closure_annotated: {}", closure_annotated(i)); + println!("closure_inferred: {}", closure_inferred(i)); // A closure taking no arguments which returns an `i32`. // The return type is inferred. From f9731702f934f5233cbe991f5d159279b321656c Mon Sep 17 00:00:00 2001 From: francozappa Date: Mon, 10 Oct 2016 11:07:49 +0800 Subject: [PATCH 0557/1122] Add more context --- examples/fn/closures/closures.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/fn/closures/closures.rs b/examples/fn/closures/closures.rs index 82002ff427..dc5f197219 100644 --- a/examples/fn/closures/closures.rs +++ b/examples/fn/closures/closures.rs @@ -2,6 +2,7 @@ fn main() { // Increment via closures and functions. fn function (i: i32) -> i32 { i + 1 } + // Closures are anonymous, here we are binding them to references // Annotation is identical to function annotation but is optional // as are the `{}` wrapping the body. These nameless functions // are assigned to appropriately named variables. From 9f5f8841eb1d88d62074593606a1bf4b1a8e7df4 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:09:13 +0800 Subject: [PATCH 0558/1122] Implicit return --- examples/fn/closures/input_parameters/input_parameters.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs index 1ad6017051..07957770b4 100644 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -4,7 +4,7 @@ fn apply(f: F) where F: FnOnce() { // ^ TODO: Try changing this to `Fn` or `FnMut`. - f() + f(); } // A function which takes a closure and returns an `i32`. @@ -17,7 +17,7 @@ fn apply_to_3(f: F) -> i32 where fn main() { use std::mem; - + let greeting = "hello"; // A non-copy type. let mut farewell = "goodbye".to_owned(); From 1866b233bb6a27e35e742e8c2b7c118b80ad6fa7 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:18:34 +0800 Subject: [PATCH 0559/1122] Comment about to_owned --- examples/fn/closures/input_parameters/input_parameters.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs index 07957770b4..4744f2d206 100644 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -20,6 +20,7 @@ fn main() { let greeting = "hello"; // A non-copy type. + // `to_owned` creates owned data from borrowed one let mut farewell = "goodbye".to_owned(); // Capture 2 variables: `greeting` by reference and From 320024d39adba4d6d1a86183b511e882772765ae Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:28:22 +0800 Subject: [PATCH 0560/1122] Comment double closure parameter --- examples/fn/closures/input_parameters/input_parameters.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs index 4744f2d206..dadfa2e44b 100644 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -43,6 +43,7 @@ fn main() { // Call the function which applies the closure. apply(diary); + // `double` satisfies `apply_to_3`'s trait bound let double = |x| 2 * x; println!("3 doubled: {}", apply_to_3(double)); From 06abef8234282d8a7f3873530e261451f6740939 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:46:55 +0800 Subject: [PATCH 0561/1122] Focus on closure as function parameter --- examples/fn/closures/anonymity/input.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index def2f341bf..2cef887290 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -1,6 +1,7 @@ Closures succinctly capture variables from enclosing scopes. Does this have -any consequences? It surely does. Observe how using a closure in a function -requires [generics], which is necessary because of how they are defined: +any consequences? It surely does. Observe how using a closure as a function +parameter requires [generics], which is necessary because of how they are +defined: ```rust // `F` must be generic. From 03cbd2d655166abab240114c1b6eb9de9dd40baf Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:47:29 +0800 Subject: [PATCH 0562/1122] Explicit return unit type --- examples/fn/closures/anonymity/anonymity.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/anonymity/anonymity.rs b/examples/fn/closures/anonymity/anonymity.rs index 38f1bb841e..6c02274d3c 100644 --- a/examples/fn/closures/anonymity/anonymity.rs +++ b/examples/fn/closures/anonymity/anonymity.rs @@ -3,7 +3,7 @@ // for `print`. fn apply(f: F) where F: Fn() { - f() + f(); } fn main() { From ae31d50ab9e2283f8c57aa76e2541b0afd73a0dc Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 08:56:48 +0800 Subject: [PATCH 0563/1122] Explicit return --- examples/fn/closures/anonymity/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index 2cef887290..69750faf9e 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -7,7 +7,7 @@ defined: // `F` must be generic. fn apply(f: F) where F: FnOnce() { - f() + f(); } ``` From 7f501a44d605fee50c5cda064dd018ed939b7199 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 09:01:05 +0800 Subject: [PATCH 0564/1122] Better function as a parameter desc --- examples/fn/closures/input_functions/input.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md index 49cf69acae..08ad79db4f 100644 --- a/examples/fn/closures/input_functions/input.md +++ b/examples/fn/closures/input_functions/input.md @@ -1,12 +1,12 @@ -Since closures may be used as arguments, you might wonder if the same can be said -about functions. And indeed they can! However, because a function can -*never* capture variables, closures are strictly more flexible. Therefore, any -function which can take a closure as an argument can also take a function. +Since closures may be used as arguments, you might wonder if the same can be said +about functions. And indeed they can! If you declare a function that takes a +closure as parameter, then any function that satisfy the trait bound of that +closure can be passed as a parameter. {input_functions.play} As an additional note, the `Fn`, `FnMut`, and `FnOnce` `traits` dictate how -a closure captures variables from the enclosing scope. +a closure captures variables from the enclosing scope. ### See also: From 45cfbe4485319c534236cc147c76006695daf2e4 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 09:02:38 +0800 Subject: [PATCH 0565/1122] Refactor names and comments --- .../input_functions/input_functions.rs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs index 3c7c26530a..ccd4f85747 100644 --- a/examples/fn/closures/input_functions/input_functions.rs +++ b/examples/fn/closures/input_functions/input_functions.rs @@ -1,17 +1,18 @@ -// Define a function which takes a function as an argument and calls it. -fn call_function(f: F) { - f() +// Define a function which takes a generic `F` argument +// bounded by `Fn`, and calls it +fn call_me(f: F) { + f(); } -// Define a simple function to be used as an input. -fn print() { +// Define a wrapper function satisfying the `Fn` bound +fn function() { println!("I'm a function!") } fn main() { - // Define a closure similar to the `print()` function above. + // Define a closure satisfying the `Fn` bound let closure = || println!("I'm a closure!"); - - call_function(closure); - call_function(print); -} \ No newline at end of file + + call_me(closure); + call_me(function); +} From 84b9afb2b4498f7fa969f9d68894f735c011acc1 Mon Sep 17 00:00:00 2001 From: francozappa Date: Tue, 11 Oct 2016 09:16:34 +0800 Subject: [PATCH 0566/1122] Explicit return value --- examples/fn/closures/input_functions/input_functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs index ccd4f85747..ea7382c67d 100644 --- a/examples/fn/closures/input_functions/input_functions.rs +++ b/examples/fn/closures/input_functions/input_functions.rs @@ -6,7 +6,7 @@ fn call_me(f: F) { // Define a wrapper function satisfying the `Fn` bound fn function() { - println!("I'm a function!") + println!("I'm a function!"); } fn main() { From 6d8ab37238e6af2715e73ec72cd581c6d01cbce0 Mon Sep 17 00:00:00 2001 From: Chen Rotem Levy Date: Wed, 12 Oct 2016 14:38:55 +0300 Subject: [PATCH 0567/1122] typo: s/expection/expectation/ --- examples/error/reenter_try/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index 822940a04f..78e3be40b1 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -38,7 +38,7 @@ necessary refactoring would most definitely not be trivial. Many libraries might get away with only implementing `Display` and adding `From` on an as needed basis. However, more serious libraries will -eventually need to meet higher expections of error handling implementation. +eventually need to meet higher expectations of error handling implementation. ### See also: From 2615578a22f2c8eb454b362882984cba59cb00f4 Mon Sep 17 00:00:00 2001 From: francozappa Date: Thu, 13 Oct 2016 21:26:31 +0800 Subject: [PATCH 0568/1122] Spellcheck :gb: --- examples/fn/closures/input_functions/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md index 08ad79db4f..a0a13b5b3f 100644 --- a/examples/fn/closures/input_functions/input.md +++ b/examples/fn/closures/input_functions/input.md @@ -1,6 +1,6 @@ Since closures may be used as arguments, you might wonder if the same can be said about functions. And indeed they can! If you declare a function that takes a -closure as parameter, then any function that satisfy the trait bound of that +closure as parameter, then any function that satisfies the trait bound of that closure can be passed as a parameter. {input_functions.play} From 9b6fca563c35c60ad9a71498b85bbbde22354e3e Mon Sep 17 00:00:00 2001 From: Chen Rotem Levy Date: Sat, 15 Oct 2016 12:31:31 +0300 Subject: [PATCH 0569/1122] Non-positive logarithm Check for non-positive logarithm value rather than negative --- examples/std/result/result.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/std/result/result.rs b/examples/std/result/result.rs index a0e8c6dfcc..f84611f5b2 100644 --- a/examples/std/result/result.rs +++ b/examples/std/result/result.rs @@ -3,7 +3,7 @@ mod checked { #[derive(Debug)] pub enum MathError { DivisionByZero, - NegativeLogarithm, + NonPositiveLogarithm, NegativeSquareRoot, } @@ -29,8 +29,8 @@ mod checked { } pub fn ln(x: f64) -> MathResult { - if x < 0.0 { - Err(MathError::NegativeLogarithm) + if x <= 0.0 { + Err(MathError::NonPositiveLogarithm) } else { Ok(x.ln()) } From 0176f3a8212e091999bca8545153106714a24545 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Fri, 21 Oct 2016 09:10:53 -0700 Subject: [PATCH 0570/1122] meta/doc: Add missing `use` and build instructions --- examples/meta/doc/doc.rs | 3 +++ examples/meta/doc/input.md | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/examples/meta/doc/doc.rs b/examples/meta/doc/doc.rs index 2f912e9ba9..9fa7edbd3e 100644 --- a/examples/meta/doc/doc.rs +++ b/examples/meta/doc/doc.rs @@ -1,3 +1,5 @@ +#![crate_name = "doc"] + /// A human being is represented here pub struct Person { /// A person must have a name, no matter how much Juliet may hate it @@ -16,6 +18,7 @@ impl Person { /// ``` /// // You can have rust code between fences inside the comments /// // If you pass --test to Rustdoc, it will even test it for you! + /// use doc::Person; /// let person = Person::new("name"); /// ``` pub fn new(name: &str) -> Person { diff --git a/examples/meta/doc/input.md b/examples/meta/doc/input.md index e386b3d5ac..1517672c4b 100644 --- a/examples/meta/doc/input.md +++ b/examples/meta/doc/input.md @@ -4,5 +4,16 @@ documentation. They are denoted by a `///`, and support [Markdown][2]. {doc.play} +To run the tests, first build the code as a library, then tell rustdoc where +to find the library so it can link it into each doctest program: + +``` +rustc doc.rs --crate-type lib +rustdoc --test --extern doc="libdoc.rs" +``` + +(When you run `cargo test` on a library crate, Cargo will automatically +generate and run the correct rustc and rustdoc commands.) + [1]: http://doc.rust-lang.org/book/documentation.html [2]: https://en.wikipedia.org/wiki/Markdown From 53b39f5922c570b033414161048cf3a3aa9ad1b6 Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Wed, 16 Nov 2016 21:30:17 -0500 Subject: [PATCH 0571/1122] Auto-scroll after clicking the `Run` button Fixes https://github.com/rust-lang/rust-by-example/issues/143 --- node_modules/gitbook-plugin-rust-playpen/book/editor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 0d37c05cb3..ea0bbd34fa 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -60,6 +60,7 @@ function initEditor() { var executeCode = function(ev) { resultDiv.style.display = "block"; resultDiv.innerHTML = "Running..."; + resultDiv.scrollIntoView(); // Clear previous markers, if any markers.map(function(id) { editor.getSession().removeMarker(id); }); From 2a953b3de479eb68849994cd9c0f0d3922ec84be Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Thu, 17 Nov 2016 11:54:00 -0500 Subject: [PATCH 0572/1122] fn/hof: destructure in `filter` like `take_while` This makes it more consistent with the fn/closures/closure_examples. --- examples/fn/hof/hof.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/hof/hof.rs b/examples/fn/hof/hof.rs index 44f2079515..78c187ee71 100644 --- a/examples/fn/hof/hof.rs +++ b/examples/fn/hof/hof.rs @@ -28,7 +28,7 @@ fn main() { let sum_of_squared_odd_numbers: u32 = (0..).map(|n| n * n) // All natural numbers squared .take_while(|&n| n < upper) // Below upper limit - .filter(|n| is_odd(*n)) // That are odd + .filter(|&n| is_odd(n)) // That are odd .fold(0, |sum, i| sum + i); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); } \ No newline at end of file From bf0a247e1b2eb8985a324d3f9aab96eb5f3ad3db Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Thu, 17 Nov 2016 12:21:20 -0500 Subject: [PATCH 0573/1122] error/result/result_map: fix broken link --- examples/error/result/result_map/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md index 9dd704b82b..210e1099ad 100644 --- a/examples/error/result/result_map/input.md +++ b/examples/error/result/result_map/input.md @@ -3,7 +3,7 @@ To avoid that, we need to be more specific about the return type. There, the regular element is of type `i32`. To determine the `Err` type, we look to -[`parse()`](parse), which is implemented with the [`FromStr`][from_str] trait for +[`parse()`][parse], which is implemented with the [`FromStr`][from_str] trait for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. In the example below, the straightforward `match` statement leads to code From 5c33b27a52f5df545afde20b3dc0d146bb176892 Mon Sep 17 00:00:00 2001 From: realcr Date: Fri, 18 Nov 2016 17:39:33 +0200 Subject: [PATCH 0574/1122] Removed unneeded usage of std::result. --- examples/error/result/result_alias/alias.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs index 3a948887a4..1d4ec4a440 100644 --- a/examples/error/result/result_alias/alias.rs +++ b/examples/error/result/result_alias/alias.rs @@ -1,8 +1,7 @@ use std::num::ParseIntError; -use std::result; // Define a generic alias for a `Result` with the error type `ParseIntError`. -type AliasedResult = result::Result; +type AliasedResult = Result; // Use the above alias to refer to our specific `Result` type. fn double_number(number_str: &str) -> AliasedResult { From 320023397e668ca84a0f64b04db294d46fc47b84 Mon Sep 17 00:00:00 2001 From: realcr Date: Fri, 18 Nov 2016 21:47:50 +0200 Subject: [PATCH 0575/1122] Added calibre installation requirement to README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f8811573b..9cda232746 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ Install [Rust](http://www.rust-lang.org/install.html) and run: ``` -sudo apt-get install nodejs npm subversion +sudo apt-get install nodejs npm subversion calibre sudo ln -s /usr/bin/nodejs /usr/bin/node ``` ### Non-Debian prerequisites Install Rust [nightly](http://www.rust-lang.org/install.html), -`node`, `npm`, and `subversion`. +`node`, `npm`, `subversion` and `calibre`. ### Build instructions From bb2989fcd299d804d00463afb058dd014644a4ea Mon Sep 17 00:00:00 2001 From: realcr Date: Sun, 27 Nov 2016 14:12:17 +0200 Subject: [PATCH 0576/1122] Added missing write(true) option. Fixes issue #765. --- examples/std_misc/fs/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/fs/fs.rs b/examples/std_misc/fs/fs.rs index 3f7d63cc49..d893bef58b 100644 --- a/examples/std_misc/fs/fs.rs +++ b/examples/std_misc/fs/fs.rs @@ -24,7 +24,7 @@ fn echo(s: &str, path: &Path) -> io::Result<()> { // A simple implementation of `% touch path` (ignores existing files) fn touch(path: &Path) -> io::Result<()> { - match OpenOptions::new().create(true).open(path) { + match OpenOptions::new().create(true).write(true).open(path) { Ok(_) => Ok(()), Err(e) => Err(e), } From 7cc98842d58b98539975afd9dd6ca18aa8577d6f Mon Sep 17 00:00:00 2001 From: Martijn Vermaat Date: Fri, 13 Jan 2017 22:41:25 +0100 Subject: [PATCH 0577/1122] error: Fix formatting by removig trailing spaces There's currently a line break at this point due to extraneous trailing spaces: > Noticing and explicitly managing those errors `
` > saves the rest of the program from various pitfalls. See http://rustbyexample.com/error.html --- examples/error/input.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/error/input.md b/examples/error/input.md index 679f1c84cb..1dc5837bf3 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -1,9 +1,9 @@ -Error handling is the process of handling the possibility of failure. For -example, failing to read a file and then continuing to use that *bad* input -would clearly be problematic. Noticing and explicitly managing those errors +Error handling is the process of handling the possibility of failure. For +example, failing to read a file and then continuing to use that *bad* input +would clearly be problematic. Noticing and explicitly managing those errors saves the rest of the program from various pitfalls. -For a more rigorous discussion of error handling, refer to the error +For a more rigorous discussion of error handling, refer to the error handling section in the [official book][book]. [book]: https://doc.rust-lang.org/book/error-handling.html From 0bf558dd5b0703367c15aef20aec8004d32969a7 Mon Sep 17 00:00:00 2001 From: Giang Nguyen Date: Mon, 16 Jan 2017 16:49:44 +0700 Subject: [PATCH 0578/1122] Add example struct field init shorthand --- examples/custom_types/structs/structs.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/examples/custom_types/structs/structs.rs b/examples/custom_types/structs/structs.rs index d8c538f439..6fb317b0ff 100644 --- a/examples/custom_types/structs/structs.rs +++ b/examples/custom_types/structs/structs.rs @@ -1,3 +1,11 @@ +// Enable feature field init shorthand +#![feature(field_init_shorthand)] +#[derive(Debug)] +struct Person<'a> { + name: &'a str, + age: u8 +} + // A unit struct struct Nil; @@ -18,6 +26,15 @@ struct Rectangle { } fn main() { + // Create struct with field init shorthand + let name = "Peter"; + let age = 27; + let peter = Person { name, age }; + + // Print debug struct + println!("{:?}", peter); + + // Instantiate a `Point` let point: Point = Point { x: 0.3, y: 0.4 }; From df2a69e80e900fae36f75fff95c7f00635bd01d5 Mon Sep 17 00:00:00 2001 From: Michael Brennan Date: Wed, 1 Feb 2017 22:49:54 +0100 Subject: [PATCH 0579/1122] std_misc/fs: fix expected output - Remove `walk a` lines, not mentioned in the code - Add quotes for `ls a` output --- examples/std_misc/fs/input.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/std_misc/fs/input.md b/examples/std_misc/fs/input.md index 0c147e35af..1241e16d09 100644 --- a/examples/std_misc/fs/input.md +++ b/examples/std_misc/fs/input.md @@ -15,14 +15,8 @@ $ rustc fs.rs && ./fs `cat a/c/b.txt` > hello `ls a` -> a/b.txt -> a/c -`walk a` -> a/c -> a/c/b.txt -> a/c/e.txt -> a/c/d -> a/b.txt +> "a/b.txt" +> "a/c" `rm a/c/e.txt` `rmdir a/c/d` ``` From 7674c2c5791809242ad7d476806a0e30609dea81 Mon Sep 17 00:00:00 2001 From: Jonathan Arnett Date: Thu, 9 Feb 2017 16:10:40 -0500 Subject: [PATCH 0580/1122] hello/display: Change 'Point2' to 'Point2D' I had some confusion over the naming of the 'Point2' struct, and whether it was supposed to be named 'Point2D'. This change renames the struct. Closes #841 --- examples/hello/print/print_display/display.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/hello/print/print_display/display.rs b/examples/hello/print/print_display/display.rs index d6e34d0518..05df72c8f3 100644 --- a/examples/hello/print/print_display/display.rs +++ b/examples/hello/print/print_display/display.rs @@ -15,13 +15,13 @@ impl fmt::Display for MinMax { // Define a structure where the fields are nameable for comparison. #[derive(Debug)] -struct Point2 { +struct Point2D { x: f64, y: f64, } -// Similarly, implement for Point2 -impl fmt::Display for Point2 { +// Similarly, implement for Point2D +impl fmt::Display for Point2D { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Customize so only `x` and `y` are denoted. write!(f, "x: {}, y: {}", self.x, self.y) @@ -42,7 +42,7 @@ fn main() { small = small_range, big = big_range); - let point = Point2 { x: 3.3, y: 7.2 }; + let point = Point2D { x: 3.3, y: 7.2 }; println!("Compare points:"); println!("Display: {}", point); From c8e1b8a23e61adabf104b82c7279a936cf18c1f2 Mon Sep 17 00:00:00 2001 From: projektir Date: Thu, 16 Feb 2017 00:06:42 -0500 Subject: [PATCH 0581/1122] print/print_display: changing 'Point2' to 'Point2D' under Activity --- examples/hello/print/print_display/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 3f8246ad4a..0df5450661 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -50,7 +50,7 @@ each requires its own implementation. This is detailed further in ### Activity -After checking the output of the above example, use the `Point2` struct as +After checking the output of the above example, use the `Point2D` struct as guide to add a Complex struct to the example. When printed in the same way, the output should be: ``` From adde396694401487399bac5cf2ee6a3a8f12c471 Mon Sep 17 00:00:00 2001 From: Igor Shaposhnik Date: Thu, 2 Mar 2017 21:34:23 +0300 Subject: [PATCH 0582/1122] generics/phantom/testcase_units: Fix broken link Fix #847 --- examples/generics/phantom/testcase_units/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 262e18ae63..f354c148b4 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -27,11 +27,11 @@ The whole implementation: [Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. [Borrowing (`&`)]: /scope/borrow.html -[Bounds (`X: Y`)]: /trait/bounds.html +[Bounds (`X: Y`)]: /generics/bounds.html [enum]: /custom_types/enum.html [impl & self]: /fn/methods.html [Overloading]: /trait/ops.html [ref]: /scope/borrow/ref.html [Traits (`X for Y`)]: /trait.html [TupleStructs]: /custom_types/structs.html -[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html From d26e1702579db3c2df2719fcedb2954718552e82 Mon Sep 17 00:00:00 2001 From: Russell Mackenzie Date: Thu, 9 Mar 2017 01:48:33 +0000 Subject: [PATCH 0583/1122] Add definition of 'word'. --- examples/primitives/array/input.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/primitives/array/input.md b/examples/primitives/array/input.md index 48e27d682f..8d199b15ba 100644 --- a/examples/primitives/array/input.md +++ b/examples/primitives/array/input.md @@ -4,7 +4,9 @@ at compile time, is part of their type signature `[T; size]`. Slices are similar to arrays, but their size is not known at compile time. Instead, a slice is a two-word object, the first word is a pointer to the data, -and the second word is the length of the slice. Slices can be used to borrow a -section of an array, and have the type signature `&[T]`. +and the second word is the length of the slice. The word size is the same as +usize, determined by the processor architecture eg 64 bits on an x86-64. +Slices can be used to borrow a section of an array, and have the type signature +`&[T]`. {array.play} From 57a9e4750e40bf48d339b923f2cb7829e4c7c5bc Mon Sep 17 00:00:00 2001 From: Russell Mackenzie Date: Fri, 10 Mar 2017 16:08:32 +0000 Subject: [PATCH 0584/1122] hello/print: change wording. Close #829 --- examples/hello/print/print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs index 303adddb79..6dfe4c011d 100644 --- a/examples/hello/print/print.rs +++ b/examples/hello/print/print.rs @@ -17,7 +17,7 @@ fn main() { verb="jumps over"); // Special formatting can be specified after a `:`. - println!("{} of {:b} people know binary, the other half don't", 1, 2); + println!("{} of {:b} people know binary, the other half doesn't", 1, 2); // You can right-align text with a specified width. This will output // " 1". 5 white spaces and a "1". From fb9468c590d485959b2889dfc4a0bdc87d709a25 Mon Sep 17 00:00:00 2001 From: Russell Mackenzie Date: Fri, 10 Mar 2017 18:42:26 +0000 Subject: [PATCH 0585/1122] hello/print/print_display/testcase_list: replace try! with ?. Close #834 --- .../hello/print/print_display/testcase_list/input.md | 11 +++++++++-- .../print_display/testcase_list/testcase_list.rs | 10 +++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/hello/print/print_display/testcase_list/input.md b/examples/hello/print/print_display/testcase_list/input.md index 6db364e40d..5e56c3348b 100644 --- a/examples/hello/print/print_display/testcase_list/input.md +++ b/examples/hello/print/print_display/testcase_list/input.md @@ -1,7 +1,8 @@ Implementing `fmt::Display` for a structure where the elements must each be handled sequentially is tricky. The problem is that each `write!` generates a `fmt::Result`. Proper handling of this requires dealing with *all* the -results. Rust provides the `try!` macro for exactly this purpose. +results. Rust provides the `try!` macro and alternatively the equivalent +`?` operator for exactly this purpose. Using `try!` on `write!` looks like this: @@ -11,7 +12,13 @@ Using `try!` on `write!` looks like this: try!(write!(f, "{}", value)); ``` -With `try!` available, implementing `fmt::Display` for a `Vec` is +The `?` shorthand alternative looks like this: + +```rust +write!(f, "{}", value)?; +``` + +With `?` available, implementing `fmt::Display` for a `Vec` is straightforward: {testcase_list.play} diff --git a/examples/hello/print/print_display/testcase_list/testcase_list.rs b/examples/hello/print/print_display/testcase_list/testcase_list.rs index 0f7128c72d..400ba03e31 100644 --- a/examples/hello/print/print_display/testcase_list/testcase_list.rs +++ b/examples/hello/print/print_display/testcase_list/testcase_list.rs @@ -9,15 +9,15 @@ impl fmt::Display for List { // via destructuring. let List(ref vec) = *self; - try!(write!(f, "[")); + write!(f, "[")?; // Iterate over `vec` in `v` while enumerating the iteration // count in `count`. for (count, v) in vec.iter().enumerate() { - // For every element except the first, add a comma - // before calling `write!`. Use `try!` to return on errors. - if count != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}", v)); + // For every element except the first, add a comma. + // Use the ? operator, or try!, to return on errors. + if count != 0 { write!(f, ", ")?; } + write!(f, "{}", v)?; } // Close the opened bracket and return a fmt::Result value From eeb9226ef2f92c7d0753e9876d43d123a48a583b Mon Sep 17 00:00:00 2001 From: Russell Mackenzie Date: Thu, 9 Mar 2017 14:02:48 +0000 Subject: [PATCH 0586/1122] hello/print/print_display/testcase_list: simplify example. hello/print/print_display/testcase_list: simplify example, with requested changes. Closes #833 --- .../print/print_display/testcase_list/testcase_list.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/hello/print/print_display/testcase_list/testcase_list.rs b/examples/hello/print/print_display/testcase_list/testcase_list.rs index 400ba03e31..20e6106642 100644 --- a/examples/hello/print/print_display/testcase_list/testcase_list.rs +++ b/examples/hello/print/print_display/testcase_list/testcase_list.rs @@ -5,9 +5,9 @@ struct List(Vec); impl fmt::Display for List { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Dereference `self` and create a reference to `vec` - // via destructuring. - let List(ref vec) = *self; + // Extract the value using tuple indexing + // and create a reference to `vec`. + let vec = &self.0; write!(f, "[")?; From 99c98dfccaa5b1581e369311a387f222fbff0ce3 Mon Sep 17 00:00:00 2001 From: Jacob Eiting Date: Wed, 15 Mar 2017 09:34:57 -0700 Subject: [PATCH 0587/1122] cast/alias: Fix typing ambiguity. --- examples/cast/alias/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cast/alias/input.md b/examples/cast/alias/input.md index d3328238d6..9868a5f5c7 100644 --- a/examples/cast/alias/input.md +++ b/examples/cast/alias/input.md @@ -4,7 +4,7 @@ exception to this rule are the primitive types: `usize`, `f32`, etc. {alias.play} -The main use of aliases is to reduce typing; for example the `IoResult` type +The main use of aliases is to reduce boilerplate; for example the `IoResult` type is an alias for the `Result` type. ### See also: From ce0989a8585e0b883ca8181606ddb89add44abe6 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 15 Mar 2017 11:17:02 -0700 Subject: [PATCH 0588/1122] Add pub(restricted) example --- examples/mod/visibility/visibility.rs | 63 +++++++++++++++++++-------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/examples/mod/visibility/visibility.rs b/examples/mod/visibility/visibility.rs index 95e5927cfc..343a49230b 100644 --- a/examples/mod/visibility/visibility.rs +++ b/examples/mod/visibility/visibility.rs @@ -1,39 +1,55 @@ -// A module named `my` -mod my { +// A module named `my_mod` +mod my_mod { // Items in modules default to private visibility. fn private_function() { - println!("called `my::private_function()`"); + println!("called `my_mod::private_function()`"); } - + // Use the `pub` modifier to override default visibility. pub fn function() { - println!("called `my::function()`"); + println!("called `my_mod::function()`"); } - + // Items can access other items in the same module, // even when private. pub fn indirect_access() { - print!("called `my::indirect_access()`, that\n> "); + print!("called `my_mod::indirect_access()`, that\n> "); private_function(); } // Modules can also be nested pub mod nested { pub fn function() { - println!("called `my::nested::function()`"); + println!("called `my_mod::nested::function()`"); } #[allow(dead_code)] fn private_function() { - println!("called `my::nested::private_function()`"); + println!("called `my_mod::nested::private_function()`"); } + + // Functions declared using `pub(in path)` syntax are only visible + // within the given path + pub(in my_mod) fn public_function_in_my_mod() { + println!("called `my_mod::nested::public_function_in_my_mod()`") + } + } + + pub fn call_public_function_in_my_mod() { + print!("called `my_mod::call_public_funcion_in_my_mod()`, that\n> "); + nested::public_function_in_my_mod(); + } + + // pub(crate) makes functions visible only within the current crate + pub(crate) fn public_function_in_crate() { + println!("called `my_mod::public_function_in_crate()"); } - + // Nested modules follow the same rules for visibility mod private_nested { #[allow(dead_code)] pub fn function() { - println!("called `my::private_nested::function()`"); + println!("called `my_mod::private_nested::function()`"); } } } @@ -45,25 +61,34 @@ fn function() { fn main() { // Modules allow disambiguation between items that have the same name. function(); - my::function(); - + my_mod::function(); + // Public items, including those inside nested modules, can be // accessed from outside the parent module. - my::indirect_access(); - my::nested::function(); + my_mod::indirect_access(); + my_mod::nested::function(); + my_mod::call_public_function_in_my_mod(); + + // pub(crate) items can be called from anywhere in the same crate + my_mod::public_function_in_crate(); + + // pub(in path) items can only be called from within the mode specified + // Error! function `public_function_in_my_mod` is private + //my_mod::nested::public_function_in_my_mod(); + // TODO ^ Try uncommenting this line // Private items of a module cannot be directly accessed, even if // nested in a public module: - + // Error! `private_function` is private - //my::private_function(); + //my_mod::private_function(); // TODO ^ Try uncommenting this line // Error! `private_function` is private - //my::nested::private_function(); + //my_mod::nested::private_function(); // TODO ^ Try uncommenting this line // Error! `private_nested` is a private module - //my::private_nested::function(); + //my_mod::private_nested::function(); // TODO ^ Try uncommenting this line } \ No newline at end of file From 91d25050508fa7411fdccd71aa49498fe8caf476 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Sat, 18 Mar 2017 00:05:08 -0700 Subject: [PATCH 0589/1122] Add pub(self) and pub(super) --- examples/mod/visibility/visibility.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/mod/visibility/visibility.rs b/examples/mod/visibility/visibility.rs index 343a49230b..4f4115f450 100644 --- a/examples/mod/visibility/visibility.rs +++ b/examples/mod/visibility/visibility.rs @@ -29,15 +29,30 @@ mod my_mod { } // Functions declared using `pub(in path)` syntax are only visible - // within the given path + // within the given path. `path` must be a parent or ancestor module pub(in my_mod) fn public_function_in_my_mod() { - println!("called `my_mod::nested::public_function_in_my_mod()`") - } + print!("called `my_mod::nested::public_function_in_my_mod()`, that\n > "); + public_function_in_nested() + } + + // Functions declared using `pub(self)` syntax are only visible within + // the current module + pub(self) fn public_function_in_nested() { + println!("called `my_mod::nested::public_function_in_nested"); + } + + // Functions declared using `pub(super)` syntax are only visible within + // the parent module + pub(super) fn public_function_in_super_mod() { + println!("called my_mod::nested::public_function_in_super_mod"); + } } pub fn call_public_function_in_my_mod() { print!("called `my_mod::call_public_funcion_in_my_mod()`, that\n> "); nested::public_function_in_my_mod(); + print!("> "); + nested::public_function_in_super_mod(); } // pub(crate) makes functions visible only within the current crate From ad3f1ee102193e2c31301ebdf4d433671836aa58 Mon Sep 17 00:00:00 2001 From: anoop Date: Sun, 19 Mar 2017 17:39:04 +0200 Subject: [PATCH 0590/1122] Fix for #857 inherited Debug trait for the Struct Point --- examples/std/box/box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std/box/box.rs b/examples/std/box/box.rs index 6ca5354ec8..397aca7199 100644 --- a/examples/std/box/box.rs +++ b/examples/std/box/box.rs @@ -1,6 +1,6 @@ use std::mem; -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] struct Point { x: f64, y: f64, From de1701bbd4734a696c96e1ca9dff34fa421af4c8 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Wed, 5 Apr 2017 13:58:54 +0200 Subject: [PATCH 0591/1122] additional thread example. more involved example on the slightly more challenging problem of multi-threaded map-reduce --- .../threads/testcase_mapreduce/mapreduce.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 examples/std_misc/threads/testcase_mapreduce/mapreduce.rs diff --git a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs new file mode 100644 index 0000000000..ad5ac38131 --- /dev/null +++ b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs @@ -0,0 +1,88 @@ +use std::thread; + +// This is the `main` thread +fn main() { + + // This is our data to process. + // We will calculate the sum of all digits via a threaded map-reduce algorithm. + // each whitespace separated chunk will be handled in a different thread. + // Try it: see what happens to the output if you insert spaces! + let data = "86967897737416471853297327050364959 +11861322575564723963297542624962850 +70856234701860851907960690014725639 +38397966707106094172783238747669219 +52380795257888236525459303330302837 +58495327135744041048897885734297812 +69920216438980873548808413720956532 +16278424637452589860345374828574668"; + + // Make a vector to hold the child-threads which we will spawn. + let mut children = vec![]; + + /************************************************************************* + * "Map" phase + * + * Divide our data into segments, and apply initial processing + *************************************************************************/ + + // split our data into segments for individual calculation + // each chunk will be a reference (&str) into the actual data + let chunked_data = data.split_whitespace(); + + // iterate over the data segments. + // .enumerate() adds the current loop index to whatever is iterated + // the resulting tuple "(index, element)" is then immediately "destructured" + // into two variables, "i" and "data_segment" with a "destructuring assignment" + for (i, data_segment) in chunked_data.enumerate() { + println!("data segment {} is \"{}\"", i, data_segment); + + // Process each data segment in a separate thread + // spawn() returns a handle to the new thread, which we MUST keep + // to access the returned value + // 'move || -> u32' is syntax for a closure that takes no arguments ('||'), + // takes ownership of its captured variables ('move') and returns a + // unsigned 32-bit integer ('-> u32') + // Rust is smart enough to infer the '-> u32' from the closure itself + // so we could have left that out. + children.push(thread::spawn(move || -> u32 { + // Calculate the intermediate sum of this segment: + let result = data_segment + // iterate over the characters of our segment.. + .chars() + // .. convert each text-character to its base-10 number value.. + .map(|c| c.to_digit(10).expect("should have been a digit")) + // .. and sum the resulting iterator of numbers + .sum(); + + // println! implicitly locks stdout, so no text-interleaving occurs + println!("processed segment {}, itermediate result={}", i, result); + + // "return" not needed, because Rust is an "expression language", the last + // evaluated expression in each block is automatically its value. + result + + })); + } + + + /************************************************************************* + * "Reduce" phase + * + * Collect our intermediate results, and combine them into a final result + *************************************************************************/ + + // collect each thread's intermediate results into a new Vec + let mut intermediate_sums = vec![]; + for child in children { + // collect each child thread's return-value + let intermediate_sum = child.join().unwrap(); + intermediate_sums.push(intermediate_sum); + } + + // combine all intermediate sums into a single final sum. + // we use the "turbofish" ::<> notation to provide sum() with a type hint + let final_result = intermediate_sums.iter().sum::(); + + println!("Final sum result: {}", final_result); +} + From 5901b84eaa15b0c9a3ceaa4c1a4035c1f44ef3c4 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Wed, 5 Apr 2017 14:59:42 +0200 Subject: [PATCH 0592/1122] thread testcase: provide textual explanation of additional thread example --- .../threads/testcase_mapreduce/input.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 examples/std_misc/threads/testcase_mapreduce/input.md diff --git a/examples/std_misc/threads/testcase_mapreduce/input.md b/examples/std_misc/threads/testcase_mapreduce/input.md new file mode 100644 index 0000000000..5d4ee2aae8 --- /dev/null +++ b/examples/std_misc/threads/testcase_mapreduce/input.md @@ -0,0 +1,34 @@ +Rust makes it very easy to parallelise data processing, without many of the headaches traditionally associated with such an attempt. + +The standard library provides great threading primitives out of the box. +These, combined with Rust's concept of Ownership and aliasing rules, automatically prevent data races. + +The aliasing rules (one writable reference XOR many readable references) automatically prevent you from +manipulating state that is visible to other threads. (Where synchronisation is needed, there are synchronisation +primitives like `Mutex`es or `Channel`s.) + +In this example, we will calculate the sum of all digits in a block of numbers. +We will do this by parcelling out chunks of the block into different threads. Each thread will sum its tiny block of digits, and subsequently we will sum the intermediate sums produced by each thread. +Note that, although we're passing references across thread boundaries, Rust understands that we're only passing read-only references, and that thus no unsafety or data races can occur. Because we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive until the threads exit, so no dangling pointers occur. + +{mapreduce.play} + +### See also: +* [Threads][thread] +* [vectors][vectors] and [iterators][iterators] +* [closures][closures], [move][move] semantics and [`move` closures][move_closure] +* [destructuring][destructuring] assignments +* [turbofish notation][turbofish] to help type inference +* [unwrap vs. expect][unwrap] +* [enumerate][enumerate] + +[thread]: /std_misc/threads.html +[vectors]: /std/vec.html +[iterators]: /trait/iter.html +[destructuring]: https://doc.rust-lang.org/book/patterns.html#destructuring +[closures]: /fn/closures.html +[move]: /scope/move.html +[move_closure]: https://doc.rust-lang.org/book/closures.html#move-closures +[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect +[unwrap]: /error/option_unwrap.html +[enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate From 92dfee0a1d630fd80c74d16948000ff3a3fd385b Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Wed, 5 Apr 2017 15:01:22 +0200 Subject: [PATCH 0593/1122] thread testcase: user engagement with some explicit try-it-yourself TODO's --- examples/std_misc/threads/testcase_mapreduce/mapreduce.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs index ad5ac38131..4573492c89 100644 --- a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs +++ b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs @@ -6,7 +6,7 @@ fn main() { // This is our data to process. // We will calculate the sum of all digits via a threaded map-reduce algorithm. // each whitespace separated chunk will be handled in a different thread. - // Try it: see what happens to the output if you insert spaces! + // TODO: see what happens to the output if you insert spaces! let data = "86967897737416471853297327050364959 11861322575564723963297542624962850 70856234701860851907960690014725639 @@ -44,6 +44,7 @@ fn main() { // unsigned 32-bit integer ('-> u32') // Rust is smart enough to infer the '-> u32' from the closure itself // so we could have left that out. + // TODO: try removing the 'move' and see what happens children.push(thread::spawn(move || -> u32 { // Calculate the intermediate sum of this segment: let result = data_segment @@ -81,6 +82,7 @@ fn main() { // combine all intermediate sums into a single final sum. // we use the "turbofish" ::<> notation to provide sum() with a type hint + // TODO: try without the turbofish, by instead explicitly specifying the type of intermediate_sums let final_result = intermediate_sums.iter().sum::(); println!("Final sum result: {}", final_result); From 9b8e11546783066453d5d81e42a18565fcb2062f Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Wed, 5 Apr 2017 15:03:38 +0200 Subject: [PATCH 0594/1122] add additional thread testcase to index in structure.json --- examples/structure.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index 290107d6dd..c61c03d8cf 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -172,7 +172,9 @@ ] } ] }, { "id": "std_misc", "title": "Std misc", "children": [ - { "id": "threads", "title": "Threads", "children": null }, + { "id": "threads", "title": "Threads", "children": [ + { "id": "testcase_mapreduce", "title": "Testcase: map-reduce", "children": null} + ] }, { "id": "channels", "title": "Channels", "children": null }, { "id": "path", "title": "Path", "children": null }, { "id": "file", "title": "File I/O", "children": [ From 98a339e5301a655a403a0a699296f14526e75258 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Wed, 5 Apr 2017 17:08:21 +0200 Subject: [PATCH 0595/1122] reduce everything to 80-char width for Travis, even through Docs say 99 --- .../threads/testcase_mapreduce/mapreduce.rs | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs index 4573492c89..0698669430 100644 --- a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs +++ b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs @@ -4,7 +4,8 @@ use std::thread; fn main() { // This is our data to process. - // We will calculate the sum of all digits via a threaded map-reduce algorithm. + // We will calculate the sum of all digits via a threaded + // map-reduce algorithm. // each whitespace separated chunk will be handled in a different thread. // TODO: see what happens to the output if you insert spaces! let data = "86967897737416471853297327050364959 @@ -23,7 +24,7 @@ fn main() { * "Map" phase * * Divide our data into segments, and apply initial processing - *************************************************************************/ + ************************************************************************/ // split our data into segments for individual calculation // each chunk will be a reference (&str) into the actual data @@ -31,16 +32,18 @@ fn main() { // iterate over the data segments. // .enumerate() adds the current loop index to whatever is iterated - // the resulting tuple "(index, element)" is then immediately "destructured" - // into two variables, "i" and "data_segment" with a "destructuring assignment" + // the resulting tuple "(index, element)" is then immediately + // "destructured" into two variables, "i" and "data_segment" with a + // "destructuring assignment" for (i, data_segment) in chunked_data.enumerate() { println!("data segment {} is \"{}\"", i, data_segment); // Process each data segment in a separate thread // spawn() returns a handle to the new thread, which we MUST keep // to access the returned value - // 'move || -> u32' is syntax for a closure that takes no arguments ('||'), - // takes ownership of its captured variables ('move') and returns a + // 'move || -> u32' is syntax for a closure that takes + // no arguments ('||'), takes ownership of its captured + // variables ('move') and returns an // unsigned 32-bit integer ('-> u32') // Rust is smart enough to infer the '-> u32' from the closure itself // so we could have left that out. @@ -50,16 +53,17 @@ fn main() { let result = data_segment // iterate over the characters of our segment.. .chars() - // .. convert each text-character to its base-10 number value.. - .map(|c| c.to_digit(10).expect("should have been a digit")) + // .. convert text-characters to their number value.. + .map(|c| c.to_digit(10).expect("should be a digit")) // .. and sum the resulting iterator of numbers .sum(); - // println! implicitly locks stdout, so no text-interleaving occurs - println!("processed segment {}, itermediate result={}", i, result); + // println! locks stdout, so no text-interleaving occurs + println!("processed segment {}, result={}", i, result); - // "return" not needed, because Rust is an "expression language", the last - // evaluated expression in each block is automatically its value. + // "return" not needed, because Rust is an "expression language", + // the last evaluated expression in each block is automatically + // its value. result })); @@ -70,7 +74,7 @@ fn main() { * "Reduce" phase * * Collect our intermediate results, and combine them into a final result - *************************************************************************/ + ************************************************************************/ // collect each thread's intermediate results into a new Vec let mut intermediate_sums = vec![]; @@ -81,8 +85,9 @@ fn main() { } // combine all intermediate sums into a single final sum. - // we use the "turbofish" ::<> notation to provide sum() with a type hint - // TODO: try without the turbofish, by instead explicitly specifying the type of intermediate_sums + // we use the "turbofish" ::<> to provide sum() with a type hint + // TODO: try without the turbofish, by instead explicitly specifying the + // type of intermediate_sums let final_result = intermediate_sums.iter().sum::(); println!("Final sum result: {}", final_result); From 1612a7bfa4ae2357050432819801984607e687f9 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Thu, 6 Apr 2017 16:31:08 +0200 Subject: [PATCH 0596/1122] fix comment justification as per review-nit --- .../threads/testcase_mapreduce/mapreduce.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs index 0698669430..6ad15f83d8 100644 --- a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs +++ b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs @@ -4,9 +4,9 @@ use std::thread; fn main() { // This is our data to process. - // We will calculate the sum of all digits via a threaded - // map-reduce algorithm. - // each whitespace separated chunk will be handled in a different thread. + // We will calculate the sum of all digits via a threaded map-reduce algorithm. + // Each whitespace separated chunk will be handled in a different thread. + // // TODO: see what happens to the output if you insert spaces! let data = "86967897737416471853297327050364959 11861322575564723963297542624962850 @@ -30,23 +30,27 @@ fn main() { // each chunk will be a reference (&str) into the actual data let chunked_data = data.split_whitespace(); - // iterate over the data segments. - // .enumerate() adds the current loop index to whatever is iterated - // the resulting tuple "(index, element)" is then immediately - // "destructured" into two variables, "i" and "data_segment" with a - // "destructuring assignment" + // Iterate over the data segments. + // .enumerate() adds the current loop index to whatever is iterated + // the resulting tuple "(index, element)" is then immediately + // "destructured" into two variables, "i" and "data_segment" with a + // "destructuring assignment" for (i, data_segment) in chunked_data.enumerate() { println!("data segment {} is \"{}\"", i, data_segment); // Process each data segment in a separate thread - // spawn() returns a handle to the new thread, which we MUST keep - // to access the returned value - // 'move || -> u32' is syntax for a closure that takes - // no arguments ('||'), takes ownership of its captured - // variables ('move') and returns an - // unsigned 32-bit integer ('-> u32') - // Rust is smart enough to infer the '-> u32' from the closure itself - // so we could have left that out. + // + // spawn() returns a handle to the new thread, + // which we MUST keep to access the returned value + // + // 'move || -> u32' is syntax for a closure that: + // * takes no arguments ('||') + // * takes ownership of its captured variables ('move') and + // * returns an unsigned 32-bit integer ('-> u32') + // + // Rust is smart enough to infer the '-> u32' from + // the closure itself so we could have left that out. + // // TODO: try removing the 'move' and see what happens children.push(thread::spawn(move || -> u32 { // Calculate the intermediate sum of this segment: @@ -61,9 +65,8 @@ fn main() { // println! locks stdout, so no text-interleaving occurs println!("processed segment {}, result={}", i, result); - // "return" not needed, because Rust is an "expression language", - // the last evaluated expression in each block is automatically - // its value. + // "return" not needed, because Rust is an "expression language", the + // last evaluated expression in each block is automatically its value. result })); @@ -85,9 +88,11 @@ fn main() { } // combine all intermediate sums into a single final sum. - // we use the "turbofish" ::<> to provide sum() with a type hint - // TODO: try without the turbofish, by instead explicitly specifying the - // type of intermediate_sums + // + // we use the "turbofish" ::<> to provide sum() with a type hint. + // + // TODO: try without the turbofish, by instead explicitly + // specifying the type of intermediate_sums let final_result = intermediate_sums.iter().sum::(); println!("Final sum result: {}", final_result); From 4e95d6f3ff45907af44b676929e412d5c4bec230 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Thu, 6 Apr 2017 16:35:46 +0200 Subject: [PATCH 0597/1122] fix justification as per review-nit: markdown --- .../threads/testcase_mapreduce/input.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/std_misc/threads/testcase_mapreduce/input.md b/examples/std_misc/threads/testcase_mapreduce/input.md index 5d4ee2aae8..dba36e3eb5 100644 --- a/examples/std_misc/threads/testcase_mapreduce/input.md +++ b/examples/std_misc/threads/testcase_mapreduce/input.md @@ -1,15 +1,23 @@ Rust makes it very easy to parallelise data processing, without many of the headaches traditionally associated with such an attempt. The standard library provides great threading primitives out of the box. -These, combined with Rust's concept of Ownership and aliasing rules, automatically prevent data races. +These, combined with Rust's concept of Ownership and aliasing rules, automatically prevent +data races. -The aliasing rules (one writable reference XOR many readable references) automatically prevent you from -manipulating state that is visible to other threads. (Where synchronisation is needed, there are synchronisation +The aliasing rules (one writable reference XOR many readable references) automatically prevent +you from manipulating state that is visible to other threads. (Where synchronisation is needed, +there are synchronisation primitives like `Mutex`es or `Channel`s.) In this example, we will calculate the sum of all digits in a block of numbers. -We will do this by parcelling out chunks of the block into different threads. Each thread will sum its tiny block of digits, and subsequently we will sum the intermediate sums produced by each thread. -Note that, although we're passing references across thread boundaries, Rust understands that we're only passing read-only references, and that thus no unsafety or data races can occur. Because we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive until the threads exit, so no dangling pointers occur. +We will do this by parcelling out chunks of the block into different threads. Each thread will sum +its tiny block of digits, and subsequently we will sum the intermediate sums produced by each +thread. + +Note that, although we're passing references across thread boundaries, Rust understands that we're +only passing read-only references, and that thus no unsafety or data races can occur. Because +we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive +until the threads exit, so no dangling pointers occur. {mapreduce.play} From f4915a3fe0ddb4f07a3eadb2c1cb9ac6a397ebbc Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Thu, 6 Apr 2017 16:38:04 +0200 Subject: [PATCH 0598/1122] add assignment to make people think about thread-DoS'ing --- examples/std_misc/threads/testcase_mapreduce/input.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/std_misc/threads/testcase_mapreduce/input.md b/examples/std_misc/threads/testcase_mapreduce/input.md index dba36e3eb5..07d963230d 100644 --- a/examples/std_misc/threads/testcase_mapreduce/input.md +++ b/examples/std_misc/threads/testcase_mapreduce/input.md @@ -21,6 +21,12 @@ until the threads exit, so no dangling pointers occur. {mapreduce.play} +### Assignments +It is not wise to let our number of threads depend on user inputted data. +What if the user decides to insert a lot of spaces? Do we _really_ want to spawn 2.000 threads? +Modify the program so that the data is always chunked into a limited number of chunks, +defined by a static constant at the beginning of the program. + ### See also: * [Threads][thread] * [vectors][vectors] and [iterators][iterators] From be55f8992ae515139561a823c18dd62e3659fe66 Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Thu, 6 Apr 2017 16:54:18 +0200 Subject: [PATCH 0599/1122] make check-line-lenght.sh report consistently with contribution guidelines --- check-line-length.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-line-length.sh b/check-line-length.sh index b42ce47701..4fd0138fc4 100755 --- a/check-line-length.sh +++ b/check-line-length.sh @@ -17,8 +17,8 @@ if [[ $status == 0 ]]; then continue fi any_offender=true - echo "> $suspect exceeds 79 chars" - awk 'length($0) > 79' $suspect + echo "> $suspect exceeds 99 chars" + awk 'length($0) > 99' $suspect done fi From 465dd4cf02f1633b78f822d36c70bef9b7e8a35b Mon Sep 17 00:00:00 2001 From: Jules Kerssemakers Date: Fri, 7 Apr 2017 09:44:48 +0200 Subject: [PATCH 0600/1122] review nit: correct English numerical punctuation of 2,000 --- examples/std_misc/threads/testcase_mapreduce/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/threads/testcase_mapreduce/input.md b/examples/std_misc/threads/testcase_mapreduce/input.md index 07d963230d..936fd9f784 100644 --- a/examples/std_misc/threads/testcase_mapreduce/input.md +++ b/examples/std_misc/threads/testcase_mapreduce/input.md @@ -23,7 +23,7 @@ until the threads exit, so no dangling pointers occur. ### Assignments It is not wise to let our number of threads depend on user inputted data. -What if the user decides to insert a lot of spaces? Do we _really_ want to spawn 2.000 threads? +What if the user decides to insert a lot of spaces? Do we _really_ want to spawn 2,000 threads? Modify the program so that the data is always chunked into a limited number of chunks, defined by a static constant at the beginning of the program. From 136393e18c545210935ffb4853c01e8787754cda Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Sun, 7 May 2017 20:02:40 -0500 Subject: [PATCH 0601/1122] scope/lifetime/static_lifetime: Fix typo. --- examples/scope/lifetime/static_lifetime/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/scope/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md index c62556e8c6..95f4fd9046 100644 --- a/examples/scope/lifetime/static_lifetime/input.md +++ b/examples/scope/lifetime/static_lifetime/input.md @@ -1,6 +1,6 @@ -A `'static` lifetime is longest possible lifetime, and lasts for +A `'static` lifetime is the longest possible lifetime, and lasts for the lifetime of the running program. A `'static` lifetime may also be -coerced to a shorter lifetimes. There are two ways to make a variable +coerced to a shorter lifetime. There are two ways to make a variable with `'static` lifetime, and both are stored in the read-only memory of the binary: From 7bb2da68c1d75b2c6d10db354a45901f28fd899b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 12 May 2017 21:06:30 +0800 Subject: [PATCH 0602/1122] fix broken links --- examples/hello/print/print_debug/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/print_debug/input.md b/examples/hello/print/print_debug/input.md index 9816fc2bc1..de5d5baef3 100644 --- a/examples/hello/print/print_debug/input.md +++ b/examples/hello/print/print_debug/input.md @@ -30,8 +30,8 @@ elegance. Manually implementing `fmt::Display` will fix that. [attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], and [`struct`][structs] -[attributes]: http://doc.rust-lang.org/reference.html#attributes +[attributes]: https://doc.rust-lang.org/reference/attributes.html [derive]: /trait/derive.html -[fmt]: http://doc.rust-lang.org/std/fmt/ +[fmt]: https://doc.rust-lang.org/std/fmt/ [structs]: /custom_types/structs.html From 4711ba7a272ddf0475b69aeb958d0e2fcbf5df7f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sat, 13 May 2017 14:07:06 +0200 Subject: [PATCH 0603/1122] flow_control/loop: add example about returning values with break This commit adds an example for the loop_break_value feature. --- examples/flow_control/loop/return/input.md | 6 ++++++ examples/flow_control/loop/return/return.rs | 13 +++++++++++++ examples/structure.json | 3 ++- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 examples/flow_control/loop/return/input.md create mode 100644 examples/flow_control/loop/return/return.rs diff --git a/examples/flow_control/loop/return/input.md b/examples/flow_control/loop/return/input.md new file mode 100644 index 0000000000..54989239bf --- /dev/null +++ b/examples/flow_control/loop/return/input.md @@ -0,0 +1,6 @@ +One of the uses of a `loop` is to retry an operation until it succeded. If the +operation returns a value though, you might need to pass it to the rest of the +code: put it after the `break`, and it will be returned by the `loop` +expression. + +{return.play} diff --git a/examples/flow_control/loop/return/return.rs b/examples/flow_control/loop/return/return.rs new file mode 100644 index 0000000000..41810b0999 --- /dev/null +++ b/examples/flow_control/loop/return/return.rs @@ -0,0 +1,13 @@ +fn main() { + let mut counter = 0; + + let result = loop { + counter += 1; + + if counter == 10 { + break counter * 2; + } + }; + + assert_eq!(result, 20); +} diff --git a/examples/structure.json b/examples/structure.json index 290107d6dd..dc3b305e55 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -37,7 +37,8 @@ { "id": "flow_control", "title": "Flow Control", "children": [ { "id": "if_else", "title": "if/else", "children": null }, { "id": "loop", "title": "loop", "children": [ - { "id": "nested", "title": "Nesting and labels", "children": null } + { "id": "nested", "title": "Nesting and labels", "children": null }, + { "id": "return", "title": "Returning from loops", "children": null } ] }, { "id": "while", "title": "while", "children": null }, { "id": "for", "title": "for and range", "children": null }, From 7011eb7f993cfbba018428fd1d2d804e7056f2c5 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Sun, 21 May 2017 19:05:16 +0200 Subject: [PATCH 0604/1122] Use [Open|Closed]Box Similar to how `[safe|block]list` is better terminology I think the same concerns apply here. This commit changes this exapmle to use `[Open|Closed]Box`. --- examples/mod/struct_visibility/struct.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/mod/struct_visibility/struct.rs b/examples/mod/struct_visibility/struct.rs index 59bb171ed8..bc91ec1773 100644 --- a/examples/mod/struct_visibility/struct.rs +++ b/examples/mod/struct_visibility/struct.rs @@ -1,19 +1,19 @@ mod my { // A public struct with a public field of generic type `T` - pub struct WhiteBox { + pub struct OpenBox { pub contents: T, } // A public struct with a private field of generic type `T` #[allow(dead_code)] - pub struct BlackBox { + pub struct ClosedBox { contents: T, } - impl BlackBox { + impl ClosedBox { // A public constructor method - pub fn new(contents: T) -> BlackBox { - BlackBox { + pub fn new(contents: T) -> ClosedBox { + ClosedBox { contents: contents, } } @@ -22,22 +22,22 @@ mod my { fn main() { // Public structs with public fields can be constructed as usual - let white_box = my::WhiteBox { contents: "public information" }; + let open_box = my::OpenBox { contents: "public information" }; // and their fields can be normally accessed. - println!("The white box contains: {}", white_box.contents); + println!("The open box contains: {}", open_box.contents); // Public structs with private fields cannot be constructed using field names. - // Error! `BlackBox` has private fields - //let black_box = my::BlackBox { contents: "classified information" }; + // Error! `ClosedBox` has private fields + //let closed_box = my::ClosedBox { contents: "classified information" }; // TODO ^ Try uncommenting this line // However, structs with private fields can be created using // public constructors - let _black_box = my::BlackBox::new("classified information"); + let _closed_box = my::ClosedBox::new("classified information"); // and the private fields of a public struct cannot be accessed. // Error! The `contents` field is private - //println!("The black box contains: {}", _black_box.contents); + //println!("The closed box contains: {}", _closed_box.contents); // TODO ^ Try uncommenting this line } From 1a24a98923bac3c685823d334aad4fc866c3807e Mon Sep 17 00:00:00 2001 From: Shinya Ishikawa Date: Mon, 22 May 2017 23:50:21 +0900 Subject: [PATCH 0605/1122] std/result/try: Non-positive logarithm Check for non-positive logarithm value rather than negative (according to std/result) --- examples/std/result/try/try.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/std/result/try/try.rs b/examples/std/result/try/try.rs index acca8e37ad..c7242dac41 100644 --- a/examples/std/result/try/try.rs +++ b/examples/std/result/try/try.rs @@ -2,7 +2,7 @@ mod checked { #[derive(Debug)] enum MathError { DivisionByZero, - NegativeLogarithm, + NonPositiveLogarithm, NegativeSquareRoot, } @@ -25,8 +25,8 @@ mod checked { } fn ln(x: f64) -> MathResult { - if x < 0.0 { - Err(MathError::NegativeLogarithm) + if x <= 0.0 { + Err(MathError::NonPositiveLogarithm) } else { Ok(x.ln()) } @@ -46,8 +46,8 @@ mod checked { pub fn op(x: f64, y: f64) { match op_(x, y) { Err(why) => panic!(match why { - MathError::NegativeLogarithm - => "logarithm of negative number", + MathError::NonPositiveLogarithm + => "logarithm of non-positive number", MathError::DivisionByZero => "division by zero", MathError::NegativeSquareRoot From b67c5a2cc882c059154248f885339487f7d59f08 Mon Sep 17 00:00:00 2001 From: Jonathan Rudenberg Date: Wed, 7 Jun 2017 10:45:53 -0400 Subject: [PATCH 0606/1122] Use HTTPS in links where possible Signed-off-by: Jonathan Rudenberg --- CONTRIBUTING.md | 6 +++--- README.md | 10 +++++----- add-relinks.sh | 2 +- examples/README.md | 6 +++--- examples/attribute/cfg/input.md | 4 ++-- examples/custom_types/enum/input.md | 2 +- examples/custom_types/structs/input.md | 2 +- examples/error/boxing_errors/input.md | 4 ++-- examples/error/define_error_type/input.md | 4 ++-- .../multiple_error_types/enter_try/input.md | 4 ++-- examples/error/option_unwrap/and_then/input.md | 4 ++-- examples/error/option_unwrap/input.md | 2 +- examples/error/option_unwrap/map/input.md | 4 ++-- examples/error/reenter_try/input.md | 4 ++-- examples/error/result/input.md | 4 ++-- examples/error/result/result_alias/input.md | 4 ++-- examples/error/result/result_map/input.md | 8 ++++---- .../destructuring/destructure_enum/input.md | 2 +- examples/flow_control/while/input.md | 2 +- examples/fn/closures/anonymity/input.md | 8 ++++---- examples/fn/closures/capture/input.md | 2 +- .../closures/closure_examples/iter_any/input.md | 2 +- .../closures/closure_examples/iter_find/input.md | 2 +- examples/fn/closures/input_functions/input.md | 6 +++--- examples/fn/closures/input_parameters/input.md | 8 ++++---- examples/fn/closures/output_parameters/input.md | 6 +++--- examples/fn/hof/input.md | 4 ++-- examples/generics/assoc_items/input.md | 2 +- examples/generics/bounds/testcase_empty/input.md | 4 ++-- examples/generics/gen_trait/input.md | 2 +- examples/generics/impl/input.md | 2 +- examples/hello/print/fmt/input.md | 8 ++++---- examples/hello/print/input.md | 2 +- examples/hello/print/print_display/input.md | 2 +- examples/meta/doc/input.md | 2 +- examples/primitives/input.md | 2 +- examples/primitives/literals/input.md | 2 +- examples/scope/lifetime/elision/input.md | 2 +- examples/scope/raii/input.md | 2 +- examples/std/hash/alt_key_types/input.md | 4 ++-- examples/std/hash/hashset/input.md | 4 ++-- examples/std/hash/input.md | 2 +- examples/std/input.md | 2 +- examples/std/result/try/input.md | 2 +- examples/std/str/input.md | 4 ++-- examples/std/vec/input.md | 2 +- examples/std_misc/input.md | 2 +- examples/trait/derive/input.md | 16 ++++++++-------- examples/trait/iter/input.md | 2 +- examples/trait/ops/input.md | 4 ++-- examples/unsafe/input.md | 2 +- 51 files changed, 97 insertions(+), 97 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 11415641b1..981c9f3a85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ not the case, leave your request as a comment on that issue. Please include the example id in the issue title, e.g. "variables/mut: concept not clear". The example id is the relative path in the URL without the html -extension, e.g. URL: `http://rustbyexample.com/variables/scope.html` -> id: +extension, e.g. URL: `https://rustbyexample.com/variables/scope.html` -> id: `variables/scope` If it's something simple like a typo, you can send a PR directly. @@ -69,14 +69,14 @@ See the [README][readme] for details about how the static site is generated. Instead of: - [Goto my URL](http://www.myurl.com) + [Goto my URL](https://www.example.com) Use: [Goto my URL][1] (Bottom of page) - [1]: http://www.myurl.com + [1]: https://www.example.com ## Rust code (.rs) diff --git a/README.md b/README.md index 9cda232746..1705d563e0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See [CONTRIBUTING.md][how-to-contribute]. ### Debian (Ubuntu) prerequisites -Install [Rust](http://www.rust-lang.org/install.html) and +Install [Rust](https://www.rust-lang.org/install.html) and run: ``` @@ -24,7 +24,7 @@ sudo ln -s /usr/bin/nodejs /usr/bin/node ### Non-Debian prerequisites -Install Rust [nightly](http://www.rust-lang.org/install.html), +Install Rust [nightly](https://www.rust-lang.org/install.html), `node`, `npm`, `subversion` and `calibre`. ### Build instructions @@ -111,10 +111,10 @@ See LICENSE-APACHE and LICENSE-MIT for more details. [travis-image]: https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master [travis-link]: https://travis-ci.org/rust-lang/rust-by-example -[website]: http://rustbyexample.com +[website]: https://rustbyexample.com [how-to-contribute]: CONTRIBUTING.md -[rust-lang]: http://www.rust-lang.org/ -[gitbook]: http://www.gitbook.io +[rust-lang]: https://www.rust-lang.org/ +[gitbook]: https://www.gitbook.io [gitbook-format]: https://github.com/GitbookIO/gitbook#book-format [main-rs]: src/main.rs [structure]: examples/structure.json diff --git a/add-relinks.sh b/add-relinks.sh index a77376bad9..6b234ef824 100755 --- a/add-relinks.sh +++ b/add-relinks.sh @@ -2,7 +2,7 @@ for example in $(ls examples); do if [[ -d examples/${example} ]]; then - new_html=http://rustbyexample.com/${example}.html + new_html=https://rustbyexample.com/${example}.html mkdir -p stage/_book/examples/${example} echo ' diff --git a/examples/README.md b/examples/README.md index 0a1017055c..b295932fb5 100644 --- a/examples/README.md +++ b/examples/README.md @@ -11,7 +11,7 @@ Additionally for the curious, you can also [check out the source code for this s Now let's begin! -[rust]: http://www.rust-lang.org/ -[install]: http://www.rust-lang.org/install.html -[std]: http://doc.rust-lang.org/std/ +[rust]: https://www.rust-lang.org/ +[install]: https://www.rust-lang.org/install.html +[std]: https://doc.rust-lang.org/std/ [home]: https://github.com/rust-lang/rust-by-example diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md index 3e7df7ba88..9c59803218 100644 --- a/examples/attribute/cfg/input.md +++ b/examples/attribute/cfg/input.md @@ -11,6 +11,6 @@ Both utilize identical argument syntax. [the reference][ref], [`cfg!`][cfg], and [macros][macros]. -[cfg]: http://doc.rust-lang.org/std/macro.cfg!.html +[cfg]: https://doc.rust-lang.org/std/macro.cfg!.html [macros]: /macros.html -[ref]: http://doc.rust-lang.org/reference.html#conditional-compilation +[ref]: https://doc.rust-lang.org/reference.html#conditional-compilation diff --git a/examples/custom_types/enum/input.md b/examples/custom_types/enum/input.md index e4b426be2c..f32001af09 100644 --- a/examples/custom_types/enum/input.md +++ b/examples/custom_types/enum/input.md @@ -9,7 +9,7 @@ an `enum`. [`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] [attributes]: /attribute.html -[c_struct]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [match]: /flow_control/match.html [fn]: /fn.html [str]: /std/str.html diff --git a/examples/custom_types/structs/input.md b/examples/custom_types/structs/input.md index 071d20883e..73bba902d2 100644 --- a/examples/custom_types/structs/input.md +++ b/examples/custom_types/structs/input.md @@ -18,5 +18,5 @@ There are three types of structures ("structs") that can be created using the [`attributes`][attributes] and [destructuring][destructuring] [attributes]: /attribute.html -[c_struct]: http://en.wikipedia.org/wiki/Struct_(C_programming_language) +[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [destructuring]: /flow_control/match/destructuring.html diff --git a/examples/error/boxing_errors/input.md b/examples/error/boxing_errors/input.md index d8136f25ad..029a930c13 100644 --- a/examples/error/boxing_errors/input.md +++ b/examples/error/boxing_errors/input.md @@ -39,5 +39,5 @@ with `DoubleError`: [Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] -[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch -[error]: http://doc.rust-lang.org/std/error/trait.Error.html +[dynamic_dispatch]: https://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch +[error]: https://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/error/define_error_type/input.md b/examples/error/define_error_type/input.md index f8e49b158c..ffe0ad3954 100644 --- a/examples/error/define_error_type/input.md +++ b/examples/error/define_error_type/input.md @@ -20,6 +20,6 @@ logic heavy code with `String` formatting simply to display nicely. [`Result`][result] and [`io::Result`][io_result] -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html [inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/error/multiple_error_types/enter_try/input.md b/examples/error/multiple_error_types/enter_try/input.md index 76a46b01cc..ce16569332 100644 --- a/examples/error/multiple_error_types/enter_try/input.md +++ b/examples/error/multiple_error_types/enter_try/input.md @@ -23,6 +23,6 @@ to make more structured and informative errors by defining their types. [`Result`][result] and [`io::Result`][io_result] -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html [re_enter_try]: /error/reenter_try.html diff --git a/examples/error/option_unwrap/and_then/input.md b/examples/error/option_unwrap/and_then/input.md index de4fa46344..8899229a06 100644 --- a/examples/error/option_unwrap/and_then/input.md +++ b/examples/error/option_unwrap/and_then/input.md @@ -17,5 +17,5 @@ Using `map()` instead of `and_then()` would have given an [closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] [closures]: /fn/closures.html -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[and_then]: https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md index e15da58adc..0070be2751 100644 --- a/examples/error/option_unwrap/input.md +++ b/examples/error/option_unwrap/input.md @@ -23,4 +23,4 @@ controlled result while retaining the option to `panic` if desired. {option_unwrap.play} -[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect +[expect]: https://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option_unwrap/map/input.md b/examples/error/option_unwrap/map/input.md index 31d7f9a1cb..ee8b481070 100644 --- a/examples/error/option_unwrap/map/input.md +++ b/examples/error/option_unwrap/map/input.md @@ -18,5 +18,5 @@ to it while staying compact. [combinators]: https://doc.rust-lang.org/book/glossary.html#combinators [closures]: /fn/closures.html -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index 78e3be40b1..01b7b00117 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -44,5 +44,5 @@ eventually need to meet higher expectations of error handling implementation. [`From::from`][from] and [`try!`][try] -[from]: http://doc.rust-lang.org/std/convert/trait.From.html -[try]: http://doc.rust-lang.org/std/macro.try!.html +[from]: https://doc.rust-lang.org/std/convert/trait.From.html +[try]: https://doc.rust-lang.org/std/macro.try!.html diff --git a/examples/error/result/input.md b/examples/error/result/input.md index d36fc16134..73929635b7 100644 --- a/examples/error/result/input.md +++ b/examples/error/result/input.md @@ -28,6 +28,6 @@ unpleasant error message. To improve the quality of our error message, we should be more specific about the return type and consider explicitly handling the error. -[option]: http://doc.rust-lang.org/std/option/enum.Option.html -[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html [parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md index 5085e5dc80..c552ff9872 100644 --- a/examples/error/result/result_alias/input.md +++ b/examples/error/result/result_alias/input.md @@ -15,5 +15,5 @@ Here's a quick example to show off the syntax: [`Result`][result] and [`io::Result`][io_result] [typealias]: /cast/alias.html -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md index 210e1099ad..fc4a857396 100644 --- a/examples/error/result/result_map/input.md +++ b/examples/error/result/result_map/input.md @@ -14,7 +14,7 @@ contains a complete listing. {result_map.play} [parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse -[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html -[i32]: http://doc.rust-lang.org/std/primitive.i32.html -[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html -[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[from_str]: https://doc.rust-lang.org/std/str/trait.FromStr.html +[i32]: https://doc.rust-lang.org/std/primitive.i32.html +[parse_int_error]: https://doc.rust-lang.org/std/num/struct.ParseIntError.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md index e532afca20..14a65cad0b 100644 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ b/examples/flow_control/match/destructuring/destructure_enum/input.md @@ -7,5 +7,5 @@ An `enum` is destructured similarly: [`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] [allow]: /attribute/unused.html -[color_models]: http://en.wikipedia.org/wiki/Color_model +[color_models]: https://en.wikipedia.org/wiki/Color_model [enum]: /custom_types/enum.html diff --git a/examples/flow_control/while/input.md b/examples/flow_control/while/input.md index b03738de6b..46befb7c1f 100644 --- a/examples/flow_control/while/input.md +++ b/examples/flow_control/while/input.md @@ -4,4 +4,4 @@ Let's write the infamous [FizzBuzz][fizzbuzz] using a `while` loop. {while.play} -[fizzbuzz]: http://en.wikipedia.org/wiki/Fizz_buzz +[fizzbuzz]: https://en.wikipedia.org/wiki/Fizz_buzz diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index 69750faf9e..c6b241f94a 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -30,7 +30,7 @@ and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or and [`FnOnce`][fn_once] [generics]: /generics.html -[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html -[fn_mut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html -[fn_once]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html -[thorough_analysis]: http://huonw.github.io/blog/2015/05/finding-closure-in-rust/ +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html +[thorough_analysis]: https://huonw.github.io/blog/2015/05/finding-closure-in-rust/ diff --git a/examples/fn/closures/capture/input.md b/examples/fn/closures/capture/input.md index 0655dcee8a..49ba656bc4 100644 --- a/examples/fn/closures/capture/input.md +++ b/examples/fn/closures/capture/input.md @@ -17,4 +17,4 @@ required. [`Box`][box] and [`std::mem::drop`][drop] [box]: /std/box.html -[drop]: http://doc.rust-lang.org/std/mem/fn.drop.html +[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/examples/fn/closures/closure_examples/iter_any/input.md b/examples/fn/closures/closure_examples/iter_any/input.md index 0780bfb96a..ad00ca4227 100644 --- a/examples/fn/closures/closure_examples/iter_any/input.md +++ b/examples/fn/closures/closure_examples/iter_any/input.md @@ -23,4 +23,4 @@ pub trait Iterator { [`std::iter::Iterator::any`][any] -[any]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any +[any]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/examples/fn/closures/closure_examples/iter_find/input.md b/examples/fn/closures/closure_examples/iter_find/input.md index 00e92c655a..cfc114f0cd 100644 --- a/examples/fn/closures/closure_examples/iter_find/input.md +++ b/examples/fn/closures/closure_examples/iter_find/input.md @@ -23,4 +23,4 @@ pub trait Iterator { [`std::iter::Iterator::find`][find] -[find]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find +[find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md index a0a13b5b3f..214b1338ff 100644 --- a/examples/fn/closures/input_functions/input.md +++ b/examples/fn/closures/input_functions/input.md @@ -12,6 +12,6 @@ a closure captures variables from the enclosing scope. [`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] -[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html -[fn_mut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html -[fn_once]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md index b85c7f46b3..fd4adf9021 100644 --- a/examples/fn/closures/input_parameters/input.md +++ b/examples/fn/closures/input_parameters/input.md @@ -30,7 +30,7 @@ In the following example, try swapping the usage of `Fn`, `FnMut`, and [`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce] -[drop]: http://doc.rust-lang.org/std/mem/fn.drop.html -[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html -[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnonce]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html +[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index 6e03da3ddd..e0f41d432d 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -25,7 +25,7 @@ closure. [Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. [box]: /std/box.html -[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html -[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnbox]: http://doc.rust-lang.org/std/boxed/trait.FnBox.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: /generics.html diff --git a/examples/fn/hof/input.md b/examples/fn/hof/input.md index 0ee321be7c..118b59317f 100644 --- a/examples/fn/hof/input.md +++ b/examples/fn/hof/input.md @@ -9,5 +9,5 @@ and [Iterator][iter] implement their fair share of HOFs. -[option]: http://doc.rust-lang.org/core/option/enum.Option.html -[iter]: http://doc.rust-lang.org/core/iter/trait.Iterator.html +[option]: https://doc.rust-lang.org/core/option/enum.Option.html +[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/generics/assoc_items/input.md b/examples/generics/assoc_items/input.md index b43eb0841b..4c0e59dace 100644 --- a/examples/generics/assoc_items/input.md +++ b/examples/generics/assoc_items/input.md @@ -9,5 +9,5 @@ patterns when the `trait` is generic over its container type. [RFC][RFC] -[items]: http://doc.rust-lang.org/reference.html#items +[items]: https://doc.rust-lang.org/reference.html#items [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md \ No newline at end of file diff --git a/examples/generics/bounds/testcase_empty/input.md b/examples/generics/bounds/testcase_empty/input.md index ecab81825a..4d74f72c0f 100644 --- a/examples/generics/bounds/testcase_empty/input.md +++ b/examples/generics/bounds/testcase_empty/input.md @@ -8,6 +8,6 @@ include any functionality, you can still use it as a bound. `Eq` and [`std::cmp::Eq`][eq], [`std::cmp::Ord`s][ord], and [`trait`s][traits] -[eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html -[ord]: http://doc.rust-lang.org/std/cmp/trait.Ord.html +[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html +[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html [traits]: /trait.html diff --git a/examples/generics/gen_trait/input.md b/examples/generics/gen_trait/input.md index 67623a2e83..0b6b919c40 100644 --- a/examples/generics/gen_trait/input.md +++ b/examples/generics/gen_trait/input.md @@ -7,6 +7,6 @@ the `Drop` `trait` as a generic method to `drop` itself and an input. [`Drop`][Drop], [`struct`][structs], and [`trait`][traits] -[Drop]: http://doc.rust-lang.org/std/ops/trait.Drop.html +[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html [structs]: /custom_types/structs.html [traits]: /trait.html diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index 39d8695854..a8947f4281 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -21,5 +21,5 @@ impl GenericVal {} [fn]: /scope/lifetime/fn.html [methods]: /fn/methods.html -[specialization_plans]: http://blog.rust-lang.org/2015/05/11/traits.html#the-future +[specialization_plans]: https://blog.rust-lang.org/2015/05/11/traits.html#the-future [structs]: /custom_types/structs.html diff --git a/examples/hello/print/fmt/input.md b/examples/hello/print/fmt/input.md index a132ef1682..2635cc4a28 100644 --- a/examples/hello/print/fmt/input.md +++ b/examples/hello/print/fmt/input.md @@ -33,8 +33,8 @@ Two hints if you get stuck: ### See also [`std::fmt`][fmt] -[argument_types]: http://doc.rust-lang.org/std/fmt/#argument-types +[argument_types]: https://doc.rust-lang.org/std/fmt/#argument-types [deadbeef]: https://en.wikipedia.org/wiki/Deadbeef#Magic_debug_values -[fmt]: http://doc.rust-lang.org/std/fmt/ -[fmt_traits]: http://doc.rust-lang.org/std/fmt/#formatting-traits -[fmt_width]: http://doc.rust-lang.org/std/fmt/#width +[fmt]: https://doc.rust-lang.org/std/fmt/ +[fmt_traits]: https://doc.rust-lang.org/std/fmt/#formatting-traits +[fmt_width]: https://doc.rust-lang.org/std/fmt/#width diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index 6cf2945e05..b26f492a1f 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -35,7 +35,7 @@ for these types. To print text for custom types, more steps are required. [`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], and [`traits`][traits] -[fmt]: http://doc.rust-lang.org/std/fmt/ +[fmt]: https://doc.rust-lang.org/std/fmt/ [macros]: /macros.html [string]: /std/str.html [structs]: /custom_types/structs.html diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 0df5450661..0be56ab081 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -64,7 +64,7 @@ Debug: Complex { real: 3.3, imag: 7.2 } [`trait`][traits], and [use][use] [derive]: /trait/derive.html -[fmt]: http://doc.rust-lang.org/std/fmt/ +[fmt]: https://doc.rust-lang.org/std/fmt/ [macros]: /macros.html [structs]: /custom_types/structs.html [traits]: /trait.html diff --git a/examples/meta/doc/input.md b/examples/meta/doc/input.md index 1517672c4b..2ae7d6e4b7 100644 --- a/examples/meta/doc/input.md +++ b/examples/meta/doc/input.md @@ -15,5 +15,5 @@ rustdoc --test --extern doc="libdoc.rs" (When you run `cargo test` on a library crate, Cargo will automatically generate and run the correct rustc and rustdoc commands.) -[1]: http://doc.rust-lang.org/book/documentation.html +[1]: https://doc.rust-lang.org/book/documentation.html [2]: https://en.wikipedia.org/wiki/Markdown diff --git a/examples/primitives/input.md b/examples/primitives/input.md index dfd07daf6f..017925fae9 100644 --- a/examples/primitives/input.md +++ b/examples/primitives/input.md @@ -19,4 +19,4 @@ floats to `f64`. [the `std` library][std] -[std]: http://doc.rust-lang.org/std/ +[std]: https://doc.rust-lang.org/std/ diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index d037ccc6fe..89fe987142 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -16,5 +16,5 @@ The operators available and their precedence [in Rust][rust op-prec] are similar {literals.play} -[rust op-prec]: http://doc.rust-lang.org/reference.html#operator-precedence +[rust op-prec]: https://doc.rust-lang.org/reference.html#operator-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages diff --git a/examples/scope/lifetime/elision/input.md b/examples/scope/lifetime/elision/input.md index b9fd562c8a..f153585c5a 100644 --- a/examples/scope/lifetime/elision/input.md +++ b/examples/scope/lifetime/elision/input.md @@ -12,4 +12,4 @@ description of elision, see [lifetime elision][elision] in the book. [elision][elision] -[elision]: http://doc.rust-lang.org/book/lifetimes.html#lifetime-elision +[elision]: https://doc.rust-lang.org/book/lifetimes.html#lifetime-elision diff --git a/examples/scope/raii/input.md b/examples/scope/raii/input.md index e504f0054f..0a8fd71488 100644 --- a/examples/scope/raii/input.md +++ b/examples/scope/raii/input.md @@ -34,6 +34,6 @@ No leaks here! [Box][box] -[raii]: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization +[raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization [box]: /std/box.html [valgrind]: http://valgrind.org/info/ \ No newline at end of file diff --git a/examples/std/hash/alt_key_types/input.md b/examples/std/hash/alt_key_types/input.md index 22c647068e..a9f09f348e 100644 --- a/examples/std/hash/alt_key_types/input.md +++ b/examples/std/hash/alt_key_types/input.md @@ -26,5 +26,5 @@ let's try making a very simple user logon system: {alt_key_types.play} -[hash]: http://en.wikipedia.org/wiki/Hash_function -[floating]: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems +[hash]: https://en.wikipedia.org/wiki/Hash_function +[floating]: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems diff --git a/examples/std/hash/hashset/input.md b/examples/std/hash/hashset/input.md index e0055be940..575d99ec1f 100644 --- a/examples/std/hash/hashset/input.md +++ b/examples/std/hash/hashset/input.md @@ -34,5 +34,5 @@ Try all of these in the following example. (Examples adapted from the [documentation.][hash-set]) -[treeset]: http://doc.rust-lang.org/std/collections/struct.BTreeSet.html -[hash-set]: http://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference +[treeset]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html +[hash-set]: https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference diff --git a/examples/std/hash/input.md b/examples/std/hash/input.md index bffd1f6edc..6f44ec1ef2 100644 --- a/examples/std/hash/input.md +++ b/examples/std/hash/input.md @@ -15,4 +15,4 @@ For more information on how hashing and hash maps (sometimes called hash tables) work, have a look at [Hash Table Wikipedia][wiki-hash] -[wiki-hash]: http://en.wikipedia.org/wiki/Hash_table +[wiki-hash]: https://en.wikipedia.org/wiki/Hash_table diff --git a/examples/std/input.md b/examples/std/input.md index bcc934871e..edffc3e5fa 100644 --- a/examples/std/input.md +++ b/examples/std/input.md @@ -12,4 +12,4 @@ the `primitives`. Some of these include: [primitives][primitives] and [the std library][std] [primitives]: /primitives.html -[std]: http://doc.rust-lang.org/std/ +[std]: https://doc.rust-lang.org/std/ diff --git a/examples/std/result/try/input.md b/examples/std/result/try/input.md index a6b15c8239..909fe86d99 100644 --- a/examples/std/result/try/input.md +++ b/examples/std/result/try/input.md @@ -8,4 +8,4 @@ and the `Ok(ok)` branch expands to an `ok` expression. Be sure to check the [documentation][docs], as there are many methods to map/compose `Result`. -[docs]: http://doc.rust-lang.org/std/result/index.html +[docs]: https://doc.rust-lang.org/std/result/index.html diff --git a/examples/std/str/input.md b/examples/std/str/input.md index cbb2c1658c..2cee4f0568 100644 --- a/examples/std/str/input.md +++ b/examples/std/str/input.md @@ -14,5 +14,5 @@ More `str`/`String` methods can be found under the [std::string][string] modules -[str]: http://doc.rust-lang.org/std/str/ -[string]: http://doc.rust-lang.org/std/string/ +[str]: https://doc.rust-lang.org/std/str/ +[string]: https://doc.rust-lang.org/std/string/ diff --git a/examples/std/vec/input.md b/examples/std/vec/input.md index 370229c862..f5a7f71bcf 100644 --- a/examples/std/vec/input.md +++ b/examples/std/vec/input.md @@ -10,4 +10,4 @@ be surpassed, the vector is reallocated with a larger capacity. More `Vec` methods can be found under the [std::vec][vec] module -[vec]: http://doc.rust-lang.org/std/vec/ +[vec]: https://doc.rust-lang.org/std/vec/ diff --git a/examples/std_misc/input.md b/examples/std_misc/input.md index 37eadeead6..ad3ba643eb 100644 --- a/examples/std_misc/input.md +++ b/examples/std_misc/input.md @@ -12,4 +12,4 @@ These expand beyond what the [primitives][primitives] provide. [primitives][primitives] and [the std library][std] [primitives]: /primitives.html -[std]: http://doc.rust-lang.org/std/ +[std]: https://doc.rust-lang.org/std/ diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index 94cb71f632..ba372f8c66 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -18,13 +18,13 @@ The following is a list of derivable traits: [`derive`][derive] [attribute]: /attribute.html -[eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html -[partial-eq]: http://doc.rust-lang.org/std/cmp/trait.PartialEq.html -[ord]: http://doc.rust-lang.org/std/cmp/trait.Ord.html -[partial-ord]: http://doc.rust-lang.org/std/cmp/trait.PartialOrd.html -[clone]: http://doc.rust-lang.org/std/clone/trait.Clone.html +[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html +[partial-eq]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html +[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html +[partial-ord]: https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html +[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html [copy]: https://doc.rust-lang.org/core/marker/trait.Copy.html -[hash]: http://doc.rust-lang.org/std/hash/trait.Hash.html -[default]: http://doc.rust-lang.org/std/default/trait.Default.html -[debug]: http://doc.rust-lang.org/std/fmt/trait.Debug.html +[hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html +[default]: https://doc.rust-lang.org/std/default/trait.Default.html +[debug]: https://doc.rust-lang.org/std/fmt/trait.Debug.html [derive]: https://doc.rust-lang.org/reference.html#derive diff --git a/examples/trait/iter/input.md b/examples/trait/iter/input.md index 08c3f28d06..7e00d32293 100644 --- a/examples/trait/iter/input.md +++ b/examples/trait/iter/input.md @@ -13,4 +13,4 @@ to those shown in the example below can be found [here][iter]. {iter.play} [intoiter]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html -[iter]: http://doc.rust-lang.org/core/iter/trait.Iterator.html +[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/trait/ops/input.md b/examples/trait/ops/input.md index e3ec9ce758..9a64946846 100644 --- a/examples/trait/ops/input.md +++ b/examples/trait/ops/input.md @@ -12,6 +12,6 @@ A list of the traits, such as `Add`, that overload operators are available [here [Add][add], [Syntax Index][syntax] -[add]: http://doc.rust-lang.org/core/ops/trait.Add.html -[ops]: http://doc.rust-lang.org/core/ops/ +[add]: https://doc.rust-lang.org/core/ops/trait.Add.html +[ops]: https://doc.rust-lang.org/core/ops/ [syntax]: https://doc.rust-lang.org/book/syntax-index.html diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index a0f85eecf1..3f14b0e881 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -1,5 +1,5 @@ As an introduction to this section, to borrow from [the official docs]( -http://doc.rust-lang.org/book/unsafe.html), "one should try to minimize the +https://doc.rust-lang.org/book/unsafe.html), "one should try to minimize the amount of unsafe code in a code base." With that in mind, let's get started! Unsafe blocks in Rust are used to bypass protections put in place by the compiler; specifically, there are four primary things that unsafe blocks are From e1c85095fa818b697aab7c20a23b25f11fea09a5 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Wed, 7 Jun 2017 11:40:54 -0400 Subject: [PATCH 0607/1122] Move from -Z no-trans to --emit=metadata This is the rigtht thing to do, and -Z is disallowed as of the next beta. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eaf807886b..f6eb35e35c 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ GITBOOK = node_modules/.bin/gitbook RUSTC = rustc STRICT = -D deprecated QUIET = -A unused-variables -A dead-code -A unused-assignments -RUSTC_NT = $(RUSTC) -Z no-trans --test $(QUIET) # ${STRICT} +RUSTC_NT = $(RUSTC) --emit=metadata --test $(QUIET) # ${STRICT} WHITELIST = examples/attribute/cfg/custom/custom.rs \ examples/scope/borrow/borrow.rs \ examples/scope/borrow/freeze/freeze.rs \ From 87de92eb10bc6e868602f07515c29bb359680535 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 8 Jun 2017 13:56:49 -0400 Subject: [PATCH 0608/1122] remove feature flag --- examples/custom_types/structs/structs.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/custom_types/structs/structs.rs b/examples/custom_types/structs/structs.rs index 6fb317b0ff..3332f88eab 100644 --- a/examples/custom_types/structs/structs.rs +++ b/examples/custom_types/structs/structs.rs @@ -1,5 +1,3 @@ -// Enable feature field init shorthand -#![feature(field_init_shorthand)] #[derive(Debug)] struct Person<'a> { name: &'a str, From 9bceceb5dc4fcebd5571a1b2d5784bd441584844 Mon Sep 17 00:00:00 2001 From: "mr.Shu" Date: Sun, 11 Jun 2017 17:54:33 +0200 Subject: [PATCH 0609/1122] std/vec: Add iteration examples * Add a few examples to `vec` on iterations (imutable/mutable/enumerated). Signed-off-by: mr.Shu --- examples/std/vec/vec.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/std/vec/vec.rs b/examples/std/vec/vec.rs index afb6d7a8c9..e89355428c 100644 --- a/examples/std/vec/vec.rs +++ b/examples/std/vec/vec.rs @@ -27,4 +27,24 @@ fn main() { // Out of bounds indexing yields a panic println!("Fourth element: {}", xs[3]); + // FIXME ^ Comment out this line + + // `Vector`s can be easily iterated over + println!("Contents of xs:"); + for x in xs.iter() { + println!("> {}"x); + } + + // A `Vector` can also be iterated over while the iteration + // count is enumerated in a separate variable (`i`) + for (i, x) in xs.iter().enumerate() { + println!("In position {} we have value {}", i, x); + } + + // Thanks to `iter_mut`, mutable `Vector`s can also be iterated + // over in a way that allows modifying each value + for x in xs.iter_mut() { + *x *= 3; + } + println!("Updated vector: {:?}", xs); } From ff1abec648767eb412e863fdeec3e70773c79605 Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Thu, 22 Jun 2017 20:36:20 +0200 Subject: [PATCH 0610/1122] Suppress a dead code warning --- examples/std/box/box.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/std/box/box.rs b/examples/std/box/box.rs index 397aca7199..91b380411f 100644 --- a/examples/std/box/box.rs +++ b/examples/std/box/box.rs @@ -1,5 +1,6 @@ use std::mem; +#[allow(dead_code)] #[derive(Debug, Clone, Copy)] struct Point { x: f64, From 3c5330e0575299132f31c44bbe7f8a9e598f7b3e Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Thu, 22 Jun 2017 23:18:14 +0200 Subject: [PATCH 0611/1122] A tiny grammar fix --- examples/std_misc/channels/channels.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/channels/channels.rs b/examples/std_misc/channels/channels.rs index 4e265c5359..ed0e293834 100644 --- a/examples/std_misc/channels/channels.rs +++ b/examples/std_misc/channels/channels.rs @@ -30,7 +30,7 @@ fn main() { let mut ids = Vec::with_capacity(NTHREADS as usize); for _ in 0..NTHREADS { // The `recv` method picks a message from the channel - // `recv` will block the current thread if there no messages available + // `recv` will block the current thread if there're no messages available ids.push(rx.recv()); } From 0044cdfee8c3453d2cf71ae547e3357d3001e3d8 Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Thu, 22 Jun 2017 23:23:00 +0200 Subject: [PATCH 0612/1122] Use underbar for an unused variable --- examples/std_misc/path/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/path/path.rs b/examples/std_misc/path/path.rs index ab183f10a4..96824b6f40 100644 --- a/examples/std_misc/path/path.rs +++ b/examples/std_misc/path/path.rs @@ -5,7 +5,7 @@ fn main() { let path = Path::new("."); // The `display` method returns a `Show`able structure - let display = path.display(); + let _display = path.display(); // `join` merges a path with a byte container using the OS specific // separator, and returns the new path From a45138a7bc49aa83b0bedbeb076d07a508941847 Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Thu, 22 Jun 2017 23:53:39 +0200 Subject: [PATCH 0613/1122] Correct child process type It's std::process::Child that represents a running child process --- examples/std_misc/process/pipe/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/process/pipe/input.md b/examples/std_misc/process/pipe/input.md index a24924510b..4d3e2744bf 100644 --- a/examples/std_misc/process/pipe/input.md +++ b/examples/std_misc/process/pipe/input.md @@ -1,4 +1,4 @@ -The `Process` struct represents a running child process, and exposes the +The `std::Child` struct represents a running child process, and exposes the `stdin`, `stdout` and `stderr` handles for interaction with the underlying process via pipes. From 7e725401fd1cd9cb0825c4b9bc8d3e4ba4bc2e7e Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Fri, 23 Jun 2017 10:40:08 +0200 Subject: [PATCH 0614/1122] meta/doc: Fix rustdoc testing command Currently suggested rustdoc command gives rustdoc: missing file operand Try 'rustdoc --help' for more information. --- examples/meta/doc/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/meta/doc/input.md b/examples/meta/doc/input.md index 2ae7d6e4b7..534aabfcc1 100644 --- a/examples/meta/doc/input.md +++ b/examples/meta/doc/input.md @@ -9,7 +9,7 @@ to find the library so it can link it into each doctest program: ``` rustc doc.rs --crate-type lib -rustdoc --test --extern doc="libdoc.rs" +rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` (When you run `cargo test` on a library crate, Cargo will automatically From da5bbbdd450da12ac7e0a4577afabd8b9d83ee46 Mon Sep 17 00:00:00 2001 From: Andrew Barchuk Date: Fri, 23 Jun 2017 10:59:22 +0200 Subject: [PATCH 0615/1122] unsafe: Link to FFI chapter directly --- examples/unsafe/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index 3f14b0e881..903476852d 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -6,8 +6,8 @@ compiler; specifically, there are four primary things that unsafe blocks are used for: * dereferencing raw pointers -* calling a function over FFI (but this is covered in a different part of the - book) +* calling a function over FFI (but this is covered in [a previous + chapter](/std_misc/ffi.html) of the book) * changing types through `std::mem::transmute` * inline assembly From 662c4d981ff972788a30113e8e94289cc5d3aef3 Mon Sep 17 00:00:00 2001 From: Karuna Murti Date: Sat, 8 Jul 2017 16:51:34 +0900 Subject: [PATCH 0616/1122] fix typo --- examples/std_misc/channels/channels.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/channels/channels.rs b/examples/std_misc/channels/channels.rs index ed0e293834..fb03ec1d2f 100644 --- a/examples/std_misc/channels/channels.rs +++ b/examples/std_misc/channels/channels.rs @@ -30,7 +30,7 @@ fn main() { let mut ids = Vec::with_capacity(NTHREADS as usize); for _ in 0..NTHREADS { // The `recv` method picks a message from the channel - // `recv` will block the current thread if there're no messages available + // `recv` will block the current thread if there are no messages available ids.push(rx.recv()); } From a9638f81b80ecaf14e180bcb99c1e467f48d2a7d Mon Sep 17 00:00:00 2001 From: Funkill Date: Mon, 10 Jul 2017 12:54:30 +0300 Subject: [PATCH 0617/1122] fixed typo --- examples/scope/borrow/ref/ref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/borrow/ref/ref.rs b/examples/scope/borrow/ref/ref.rs index ac31664526..2e8c07c3e9 100644 --- a/examples/scope/borrow/ref/ref.rs +++ b/examples/scope/borrow/ref/ref.rs @@ -40,7 +40,7 @@ fn main() { let mut mutable_tuple = (Box::new(5u32), 3u32); { - // Destructure `mutable_ tuple` to change the value of `last`. + // Destructure `mutable_tuple` to change the value of `last`. let (_, ref mut last) = mutable_tuple; *last = 2u32; } From 4a5883493f7458148fc198c346f1d6bfe1b81c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Br=C3=A1ulio=20Bezerra?= Date: Fri, 21 Jul 2017 22:02:14 -0300 Subject: [PATCH 0618/1122] Fixed all links to the Rust Reference --- examples/attribute/cfg/input.md | 2 +- examples/generics/assoc_items/input.md | 4 ++-- examples/primitives/literals/input.md | 2 +- examples/trait/derive/input.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md index 9c59803218..7b4a21a37c 100644 --- a/examples/attribute/cfg/input.md +++ b/examples/attribute/cfg/input.md @@ -13,4 +13,4 @@ Both utilize identical argument syntax. [cfg]: https://doc.rust-lang.org/std/macro.cfg!.html [macros]: /macros.html -[ref]: https://doc.rust-lang.org/reference.html#conditional-compilation +[ref]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation diff --git a/examples/generics/assoc_items/input.md b/examples/generics/assoc_items/input.md index 4c0e59dace..8d199e802f 100644 --- a/examples/generics/assoc_items/input.md +++ b/examples/generics/assoc_items/input.md @@ -9,5 +9,5 @@ patterns when the `trait` is generic over its container type. [RFC][RFC] -[items]: https://doc.rust-lang.org/reference.html#items -[RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md \ No newline at end of file +[items]: https://doc.rust-lang.org/reference/items.html +[RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index 89fe987142..62fbc1f9e1 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -16,5 +16,5 @@ The operators available and their precedence [in Rust][rust op-prec] are similar {literals.play} -[rust op-prec]: https://doc.rust-lang.org/reference.html#operator-precedence +[rust op-prec]: https://doc.rust-lang.org/reference/expressions.html#operator-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index ba372f8c66..12c9104caf 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -27,4 +27,4 @@ The following is a list of derivable traits: [hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html [default]: https://doc.rust-lang.org/std/default/trait.Default.html [debug]: https://doc.rust-lang.org/std/fmt/trait.Debug.html -[derive]: https://doc.rust-lang.org/reference.html#derive +[derive]: https://doc.rust-lang.org/reference/attributes.html#derive From bc39365146fae7e6887d888eefdf7f04aa67d7de Mon Sep 17 00:00:00 2001 From: Anthony Defranceschi Date: Mon, 31 Jul 2017 18:57:50 +0200 Subject: [PATCH 0619/1122] std_misc/path: traits outdated The `BytesContainer` trait and `FileStat` struct aren't used anymore. I've replaced `BytesContainer` with `OsStr` and `FileStat` with `Metadata`. A `See also` header and some links were added too. --- examples/std_misc/path/input.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/std_misc/path/input.md b/examples/std_misc/path/input.md index 1d95da93fc..91e3b479fa 100644 --- a/examples/std_misc/path/input.md +++ b/examples/std_misc/path/input.md @@ -4,7 +4,7 @@ two flavors of `Path`: `posix::Path`, for UNIX-like systems, and platform-specific `Path` variant. A `Path` can be created from almost any type that implements the -`BytesContainer` trait, like a string, and provides several methods to get +`OsStr` trait, like a string, and provides several methods to get information from the file/directory the path points to. Note that a `Path` is *not* internally represented as an UTF-8 string, but @@ -14,4 +14,8 @@ instead is stored as a vector of bytes (`Vec`). Therefore, converting a {path.play} Be sure to check at other `Path` methods (`posix::Path` or `windows::Path`) and -the `FileStat` struct. +the `Metadata` struct. + +### See also + +[OsStr](https://doc.rust-lang.org/std/ffi/struct.OsStr.html) and [Metadata](https://doc.rust-lang.org/std/fs/struct.Metadata.html). From a7e9676ad9cca7362baa7461f555909b42190cd3 Mon Sep 17 00:00:00 2001 From: Anthony Defranceschi Date: Mon, 31 Jul 2017 19:12:15 +0200 Subject: [PATCH 0620/1122] fixed links --- examples/std_misc/path/input.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/std_misc/path/input.md b/examples/std_misc/path/input.md index 91e3b479fa..45cdfbc49e 100644 --- a/examples/std_misc/path/input.md +++ b/examples/std_misc/path/input.md @@ -18,4 +18,7 @@ the `Metadata` struct. ### See also -[OsStr](https://doc.rust-lang.org/std/ffi/struct.OsStr.html) and [Metadata](https://doc.rust-lang.org/std/fs/struct.Metadata.html). +[OsStr][1] and [Metadata][2]. + +[1]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html +[2]: https://doc.rust-lang.org/std/fs/struct.Metadata.html From 5a5b9fae2202fdb6cbfd1cd9c13b42cb98654709 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Mon, 14 Aug 2017 15:38:56 -0700 Subject: [PATCH 0621/1122] fix typo in examples/trait/ops/input.md 'list' is singular so 'is' is the correct form of be to pair with it, not 'are'. --- examples/trait/ops/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/ops/input.md b/examples/trait/ops/input.md index 9a64946846..9421fd65bf 100644 --- a/examples/trait/ops/input.md +++ b/examples/trait/ops/input.md @@ -4,7 +4,7 @@ because operators are syntactic sugar for method calls. For example, the `+` ope `a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. -A list of the traits, such as `Add`, that overload operators are available [here][ops]. +A list of the traits, such as `Add`, that overload operators is available [here][ops]. {operator.play} From dbb2996bcf77e44f061c8862dc84bb3c45b9b953 Mon Sep 17 00:00:00 2001 From: Poan Yang Date: Tue, 15 Aug 2017 14:03:19 +0800 Subject: [PATCH 0622/1122] type/literals: fix missing circular bracket --- examples/error/reenter_try/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md index 01b7b00117..0534c043fe 100644 --- a/examples/error/reenter_try/input.md +++ b/examples/error/reenter_try/input.md @@ -3,7 +3,7 @@ Notice in the previous example that our immediate reaction to calling error type: ```rust -.and_then(|s| s.parse::() +.and_then(|s| s.parse::()) .map_err(DoubleError::Parse) ``` From e86cdeb95c16fe29f71f0e05e39e3dfcb6a55f12 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 15 Aug 2017 15:33:13 -0400 Subject: [PATCH 0623/1122] Update credentials so deployment works again Instead of encrypting it locally, I've used the website at https://travis-ci.org/rust-lang/rust-by-example/settings to set this. Hopefully Fixes #886 --- .travis.yml | 5 +---- deploy.sh | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f79717928b..98369924f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,12 +25,9 @@ notifications: email: - mdinger.bugzilla@gmail.com +# uses a personal token from @steveklabnik after_success: - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh branches: only: master - -env: - global: - - secure: "oFD/tic8JAwpMXuMDBZXV4ot6w1NLWvHQTrDKmUHSMQJC1cbbrR1p5q8XayfjtmdqQdFQmIfM6YHEKeHw//ypgObWjYS8q00OaaMDXPTdmgr1Ee4nhgkkDihT+kVij0rn96W/QvyAVoaV5hJoyUr3Nhk+mnHEYm3M+Q3LAQglRg=" diff --git a/deploy.sh b/deploy.sh index 8118df3e80..ee1cc76c44 100755 --- a/deploy.sh +++ b/deploy.sh @@ -7,7 +7,7 @@ cd stage/_book git init git config user.name "Steve Klabnik" git config user.email "steve@steveklabnik.com" -git remote add upstream "https://$GH_TOKEN@github.com/rust-lang/rust-by-example.git" +git remote add upstream "https://$GITHUB_TOKEN@github.com/rust-lang/rust-by-example.git" git fetch upstream && git reset upstream/gh-pages echo "rustbyexample.com" > CNAME From 6845594d3344ca88797ba786a66e907c49ddfb96 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 11:02:58 -0400 Subject: [PATCH 0624/1122] Convert first chapter to mdbook Now that mdbook can support the Ace editor (thanks @projektir!), we can start moving RBE over to mdbook. This removes everything but the content, sets up book.toml, and converts the first chapter. https://github.com/azerupi/mdBook/pull/338 --- .gitignore | 8 +- .travis.yml | 33 -- CONTRIBUTING.md | 89 ------ Cargo.lock | 61 ---- Cargo.toml | 11 - Makefile | 54 ---- README.md | 124 -------- add-relinks.sh | 19 -- book.json | 6 - book.toml | 6 + check-line-length.sh | 30 -- check-links.sh | 94 ------ deploy.sh | 21 -- examples/hello/comment/input.md | 18 -- examples/hello/hello.rs | 14 - examples/hello/input.md | 31 -- examples/hello/print/fmt/show.rs | 48 --- examples/hello/print/input.md | 42 --- examples/hello/print/print.rs | 42 --- examples/hello/print/print_debug/debug.rs | 25 -- examples/hello/print/print_display/display.rs | 54 ---- .../testcase_list/testcase_list.rs | 31 -- fix-edit-button.sh | 10 - .../book/editor.css | 87 ----- .../book/editor.js | 298 ------------------ .../gitbook-plugin-rust-playpen/index.js | 13 - .../gitbook-plugin-rust-playpen/package.json | 8 - setup-stage.sh | 12 - src/SUMMARY.md | 11 + src/example.rs | 104 ------ src/file.rs | 48 --- src/hello.md | 49 +++ .../comment.rs => src/hello/comment.md | 22 ++ src/hello/print.md | 87 +++++ .../fmt/input.md => src/hello/print/fmt.md | 55 +++- .../hello/print/print_debug.md | 30 +- .../hello/print/print_display.md | 59 +++- .../print/print_display/testcase_list.md | 37 ++- src/index.md | 1 + src/main.rs | 51 --- src/markdown.rs | 175 ---------- src/playpen.rs | 27 -- .../jsrepl/engines/javascript-default.js | 32 -- vendor/gitbook/jsrepl/jsrepl.js | 27 -- .../jsrepl/langs/javascript/jsrepl_js.js | 2 - vendor/gitbook/jsrepl/sandbox.html | 9 - vendor/gitbook/jsrepl/sandbox.js | 52 --- .../gitbook-plugin-livereload/plugin.js | 11 - 48 files changed, 353 insertions(+), 1825 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml delete mode 100644 Makefile delete mode 100644 README.md delete mode 100755 add-relinks.sh delete mode 100644 book.json create mode 100644 book.toml delete mode 100755 check-line-length.sh delete mode 100755 check-links.sh delete mode 100755 deploy.sh delete mode 100644 examples/hello/comment/input.md delete mode 100644 examples/hello/hello.rs delete mode 100644 examples/hello/input.md delete mode 100644 examples/hello/print/fmt/show.rs delete mode 100644 examples/hello/print/input.md delete mode 100644 examples/hello/print/print.rs delete mode 100644 examples/hello/print/print_debug/debug.rs delete mode 100644 examples/hello/print/print_display/display.rs delete mode 100644 examples/hello/print/print_display/testcase_list/testcase_list.rs delete mode 100755 fix-edit-button.sh delete mode 100644 node_modules/gitbook-plugin-rust-playpen/book/editor.css delete mode 100644 node_modules/gitbook-plugin-rust-playpen/book/editor.js delete mode 100644 node_modules/gitbook-plugin-rust-playpen/index.js delete mode 100644 node_modules/gitbook-plugin-rust-playpen/package.json delete mode 100755 setup-stage.sh create mode 100644 src/SUMMARY.md delete mode 100644 src/example.rs delete mode 100644 src/file.rs create mode 100644 src/hello.md rename examples/hello/comment/comment.rs => src/hello/comment.md (66%) create mode 100644 src/hello/print.md rename examples/hello/print/fmt/input.md => src/hello/print/fmt.md (50%) rename examples/hello/print/print_debug/input.md => src/hello/print/print_debug.md (59%) rename examples/hello/print/print_display/input.md => src/hello/print/print_display.md (62%) rename examples/hello/print/print_display/testcase_list/input.md => src/hello/print/print_display/testcase_list.md (55%) create mode 100644 src/index.md delete mode 100644 src/main.rs delete mode 100644 src/markdown.rs delete mode 100644 src/playpen.rs delete mode 100755 vendor/gitbook/jsrepl/engines/javascript-default.js delete mode 100755 vendor/gitbook/jsrepl/jsrepl.js delete mode 100755 vendor/gitbook/jsrepl/langs/javascript/jsrepl_js.js delete mode 100755 vendor/gitbook/jsrepl/sandbox.html delete mode 100755 vendor/gitbook/jsrepl/sandbox.js delete mode 100644 vendor/gitbook/plugins/gitbook-plugin-livereload/plugin.js diff --git a/.gitignore b/.gitignore index 6fde780044..7585238efe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1 @@ -bin/* -stage/* -node_modules/* -!node_modules/gitbook-plugin-rust-playpen -node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js -node_modules/gitbook-plugin-rust-playpen/book/ace -target +book diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 98369924f7..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: rust -sudo: false - -rust: - - stable - - beta - - nightly - -matrix: - allow_failures: - - rust: nightly - -install: - - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz - - tar xf node.tar.gz - - export PATH=$PATH:$pwd/node-v0.12.7-linux-x64/bin - -script: - - rustc --version - - make - - make test - - make html - -notifications: - email: - - mdinger.bugzilla@gmail.com - -# uses a personal token from @steveklabnik -after_success: - - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh - -branches: - only: master diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 981c9f3a85..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,89 +0,0 @@ -# Opening an issue - -## I would like to see an example about $TOPIC - -Please check if such topic is already part of our -[TODO list][issues-all]. If that's -not the case, leave your request as a comment on that issue. - -## There's a typo/error in example $X -## Example $X is not clear -## I have an idea for example $X - -Please include the example id in the issue title, e.g. "variables/mut: concept -not clear". The example id is the relative path in the URL without the html -extension, e.g. URL: `https://rustbyexample.com/variables/scope.html` -> id: -`variables/scope` - -If it's something simple like a typo, you can send a PR directly. - -# Sending a PR for a small fix - -If you are submitting a correction/modification to an existing chapter, please -start the commit message with the example id, e.g. "type/literals: fix typo". - -# I want to contribute an example about $TOPIC - -## Check if there is an action plan for that topic - -Look for -[issues][issues-open] -that have a C-* label: - -* C-new: A new chapter, there probably a lot to do here. - -* C-expand: Expand an existing chapter, new examples are needed. - -* C-split: The current chapter is too long, we want to split it into smaller - chunks. - -* C-taken: Someone is already working in this issue, but if there is a lot of - work to do, probably you can still help. - -## Let us know what are you working on - -If an issue about the topic already exists, leave a comment there to let us -know that you'll help. Otherwise, open a new issue mentioning what topic you -plan to work on. - -## Hack away - -See the [README][readme] for details about how the static site is generated. - -## Finally, send a PR - -* Don't forget to register the example in the `examples/structure.json` file. - -* Include the example id in the commit message header, e.g. for - `literals/string` use the message "literals: add example about strings" - -* Add a `Close #123` to the commit message, to close the issue that's been used - to track your work. - -# Code Style - -## Markdown (.md) - -* Lines should contain a maximum of 99 characters. -* Use reference style hyperlinks, for example: - -Instead of: - - [Goto my URL](https://www.example.com) - -Use: - - [Goto my URL][1] - - (Bottom of page) - [1]: https://www.example.com - -## Rust code (.rs) - -* Lines should contain a maximum of 99 characters. -* In comments, types, methods, macros and variables should be wrapped in - backticks, e.g. ``` `println!` ``` - -[issues-all]: https://github.com/rust-lang/rust-by-example/issues/ -[issues-open]: https://github.com/rust-lang/rust-by-example/issues?labels=&page=1&state=open -[readme]: README.md diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index e4ae36464f..0000000000 --- a/Cargo.lock +++ /dev/null @@ -1,61 +0,0 @@ -[root] -name = "update" -version = "0.0.1" -dependencies = [ - "regex 0.1.65 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aho-corasick" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mempool" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "regex" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mempool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-serialize" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "utf8-ranges" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 4a5aea264c..0000000000 --- a/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] - -name = "update" -version = "0.0.1" -authors = ["Jorge Aparicio ", - "Steve Klabnik "] - -[dependencies] - -rustc-serialize = "*" -regex = "*" diff --git a/Makefile b/Makefile deleted file mode 100644 index f6eb35e35c..0000000000 --- a/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -GITBOOK = node_modules/.bin/gitbook -RUSTC = rustc -STRICT = -D deprecated -QUIET = -A unused-variables -A dead-code -A unused-assignments -RUSTC_NT = $(RUSTC) --emit=metadata --test $(QUIET) # ${STRICT} -WHITELIST = examples/attribute/cfg/custom/custom.rs \ - examples/scope/borrow/borrow.rs \ - examples/scope/borrow/freeze/freeze.rs \ - examples/scope/borrow/mut/mut.rs \ - examples/trait/bounds/bounds.rs \ - examples/custom_types/constants/constants.rs \ - examples/crates/link/executable.rs \ - examples/scope/lifetime/borrow/borrow.rs \ - examples/mod/mod.rs \ - examples/hello/print/print.rs \ - examples/cast/cast.rs \ - examples/primitives/primitives.rs \ - examples/variable_bindings/scope/scope.rs \ - examples/variable_bindings/mut/mut.rs \ - examples/variable_bindings/declare/declare.rs \ - examples/std/vec/vec.rs - -srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) - -.PHONY: all html epub pdf clean test serve - -all: - ./setup-stage.sh - cargo run - -html: node_modules/gitbook - $(GITBOOK) build stage - ./fix-edit-button.sh - ./add-relinks.sh - -epub: node_modules/gitbook - $(GITBOOK) epub stage - -pdf: node_modules/gitbook - $(GITBOOK) pdf stage - -clean: - rm -rf bin stage - -test: - @$(foreach src,$(srcs),$(RUSTC_NT) $(src) || exit;) - ./check-line-length.sh - ./check-links.sh - -serve: node_modules/gitbook - $(GITBOOK) serve stage - -node_modules/gitbook: - npm install gitbook@1.5.0 diff --git a/README.md b/README.md deleted file mode 100644 index 1705d563e0..0000000000 --- a/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# Rust by Example - -[![Build Status][travis-image]][travis-link] - -## What's this? - -This is the source code of the [Rust by Example][website] website! - -## How to contribute - -See [CONTRIBUTING.md][how-to-contribute]. - -## How to generate the static site - -### Debian (Ubuntu) prerequisites - -Install [Rust](https://www.rust-lang.org/install.html) and -run: - -``` -sudo apt-get install nodejs npm subversion calibre -sudo ln -s /usr/bin/nodejs /usr/bin/node -``` - -### Non-Debian prerequisites - -Install Rust [nightly](https://www.rust-lang.org/install.html), -`node`, `npm`, `subversion` and `calibre`. - -### Build instructions - -Run: - -``` -make all -make html pdf epub -make test -``` - -View the results with `make serve`. - -### Details - -We use these tools to generate the static site: - -* [Rust][rust-lang] \o/ -* [GitBook][gitbook] - -`gitbook` will generate the site from Markdown files (see details about how it -works [here][gitbook-format]). - -Before running `gitbook`, we do a preprocessing step using -[src/main.rs][main-rs]. - -This preprocessing has two steps: - -### Generating the `SUMMARY.md` - -`SUMMARY.md` is generated from the -[examples/structure.json][structure] file. This JSON file -contains a tree-like structure of "examples". - -Each example has: - -* an id, e.g. `hello` -* a title, e.g. `Hello World` -* optionally, children, which is a vector of sub-examples, e.g. `null` -* a directory under `examples`, e.g. [examples/hello][hello-folder] -* an entry in examples/structure.json, e.g. - `{ "id": "hello", "title": "Hello World", "children": null }` -* some source file(s), e.g. [examples/hello/hello.rs][hello-rs] -* an input markdown file, e.g. - [examples/hello/input.md][hello-md] - -When dealing with a child example, the path will have to include the id of its -ancestors; e.g. `examples/variable/mut/input.md`, implies that a `mut` example -lives under the `variable` example. - -### Processing `input.md` - -Instead of including the Rust code directly in `input.md`, the code lives in -separate source files; the preprocessing step will insert the source code -into the Markdown file. - -For example, to insert the source code of the `hello.rs` file, the following -syntax is used in the Markdown file: - -* `{hello.play}` expands the source code embedded in a live code editor -* `{hello.rs}` expands to static/plain source code. -* `{hello.out}` expands to the output of executing the source code. - -The Makefile provides the following recipes: - -* `make`: builds `update.rs` and does the preprocessing step -* `make book`: runs `gitbook` to generate the book -* `make serve`: runs `gitbook --serve` to generate the book and publishes it - under `localhost:4000` -* `make test`: will check all the rust source files for compilation errors - -## Translations to other languages - -* [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) -* [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) - -## License - -Rust by Example is dual-licensed under the Apache 2.0 license and the MIT -license. - -See LICENSE-APACHE and LICENSE-MIT for more details. - -[travis-image]: https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master -[travis-link]: https://travis-ci.org/rust-lang/rust-by-example -[website]: https://rustbyexample.com -[how-to-contribute]: CONTRIBUTING.md -[rust-lang]: https://www.rust-lang.org/ -[gitbook]: https://www.gitbook.io -[gitbook-format]: https://github.com/GitbookIO/gitbook#book-format -[main-rs]: src/main.rs -[structure]: examples/structure.json -[hello-folder]: examples/hello -[hello-rs]: examples/hello/hello.rs -[hello-md]: examples/hello/input.md - diff --git a/add-relinks.sh b/add-relinks.sh deleted file mode 100755 index 6b234ef824..0000000000 --- a/add-relinks.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -for example in $(ls examples); do - if [[ -d examples/${example} ]]; then - new_html=https://rustbyexample.com/${example}.html - - mkdir -p stage/_book/examples/${example} - echo ' - - - - - - -' > stage/_book/examples/${example}/README.html - fi -done diff --git a/book.json b/book.json deleted file mode 100644 index 365974f0d1..0000000000 --- a/book.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": ["rust-playpen"], - "pluginsConfig": { - "rust-playpen": {} - } -} diff --git a/book.toml b/book.toml new file mode 100644 index 0000000000..af3ded6d77 --- /dev/null +++ b/book.toml @@ -0,0 +1,6 @@ +title = "Rust By Example" +description = "A description" +author = "The Rust Community" + +[output.html.playpen] +editable = true diff --git a/check-line-length.sh b/check-line-length.sh deleted file mode 100755 index 4fd0138fc4..0000000000 --- a/check-line-length.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -WHITELIST=( - ./examples/lifetime/borrow/borrow.rs - ./src/playpen.rs -) - -echo "Checking if any rust file has a line longer than 99 characters" - -suspects=$(find . -name '*.rs' | xargs grep -El ".{100}") -status=$? - -any_offender=false -if [[ $status == 0 ]]; then - for suspect in $suspects; do - if [[ " ${WHITELIST[*]} " == *" ${suspect} "* ]]; then - continue - fi - any_offender=true - echo "> $suspect exceeds 99 chars" - awk 'length($0) > 99' $suspect - done - -fi - -if $any_offender; then - exit 1 -else - echo "All is good!" -fi diff --git a/check-links.sh b/check-links.sh deleted file mode 100755 index 2579f03a51..0000000000 --- a/check-links.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -# -# Extract links from Markdown documents, and check -# their HTTP status. Flag anything that doesn't -# return a 200. -# - -DELIMITER="{{-%%-}}" - -echo "Checking links..." - -any_bad_links=false - -files=$(find ./examples -name "*.md") - -for file in $files ; do - - # - # Extract the urls, if any, along with the line numbers. - # - reference_style_links=$(grep -n "^\[[^]]\+\]:\ http" $file | \ - sed -e "s/:/$DELIMITER/" -e "s/\[[^]]*\]: //") - - inline_links=$(grep -no "\[[^]]\+\]([^[:space:]]\+)" $file | \ - sed -e "s/:/$DELIMITER/" -e "s/\[[^]]*\](//" -e "s/)$//") - - if [[ $reference_style_links == "" && $inline_links == "" ]]; then - continue - elif [[ $reference_style_links == "" ]]; then - all_links="$inline_links" - elif [[ $inline_links == "" ]]; then - all_links="$reference_style_links" - else - all_links=$(echo "$reference_style_links"$'\n'"$inline_links" | sort -n) - fi - - for link in $all_links ; do - - url=$(echo $link | awk -F"$DELIMITER" '{print $2}') - - # Check relative, internal, urls - if [[ ! $url == http://* ]] && [[ ! $url == https://* ]]; then - - local_path=$url - - # Remove the .html if present - if [[ $local_path == *.html ]]; then - local_path=${local_path:0:${#local_path}-5} - fi - - # Build the local directory path - # This depends on the GitBook style directory structure - if [[ ! $local_path == /* ]]; then - local_path="./examples/$local_path" - else - local_path="./examples$local_path" - fi - - if [[ -d $local_path ]]; then - continue - fi - - status_code="404" - - # Check external urls - else - - # -s: silent - # -L: follow redirect - # -o: send output to /dev/null - # -I: load headers only - # -w: write the status code to stdout - status_code=$(curl -s -L -o /dev/null -I -w "%{http_code}" "$url") - - if [[ $status_code == "200" ]]; then - continue - fi - fi - - any_bad_links=true - - line_number=$(echo $link | awk -F"$DELIMITER" '{print $1}') - - echo -e "Bad link in $file:$line_number [$status_code] $url" - done - -done - -if $any_bad_links; then - echo "Some links were bad." -else - echo "All links are 200!" -fi diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index ee1cc76c44..0000000000 --- a/deploy.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -rev=$(git rev-parse --short HEAD) - -cd stage/_book - -git init -git config user.name "Steve Klabnik" -git config user.email "steve@steveklabnik.com" -git remote add upstream "https://$GITHUB_TOKEN@github.com/rust-lang/rust-by-example.git" -git fetch upstream && git reset upstream/gh-pages - -echo "rustbyexample.com" > CNAME -cp -r ../../vendor/gitbook/* gitbook/ - -touch . - -git add -A . - -git commit -m "rebuild pages at ${rev}" -git push -q upstream HEAD:gh-pages diff --git a/examples/hello/comment/input.md b/examples/hello/comment/input.md deleted file mode 100644 index 7399fbfbfb..0000000000 --- a/examples/hello/comment/input.md +++ /dev/null @@ -1,18 +0,0 @@ -Any program requires comments and indeed Rust supports -a few different varieties: - -* *Regular comments* which are ignored by the compiler: - - `// Line comments which go to the end of the line.` - - `/* Block comments which go to the closing delimiter. */` -* *Doc comments* which are parsed into HTML library -[documentation][docs]: - - `/// Generate library docs for the following item.` - - `//! Generate library docs for the enclosing item.` - -{comment.play} - -### See also: - -[Library documentation][docs] - -[docs]: /meta/doc.html diff --git a/examples/hello/hello.rs b/examples/hello/hello.rs deleted file mode 100644 index 35763efe3f..0000000000 --- a/examples/hello/hello.rs +++ /dev/null @@ -1,14 +0,0 @@ -// This is a comment, and will be ignored by the compiler -// You can test this code by clicking the "Run" button over there -> -// or if prefer to use your keyboard, you can use the "Ctrl + Enter" shortcut - -// This code is editable, feel free to hack it! -// You can always return to the original code by clicking the "Reset" button -> - -// This is the main function -fn main() { - // The statements here will be executed when the compiled binary is called - - // Print text to the console - println!("Hello World!"); -} diff --git a/examples/hello/input.md b/examples/hello/input.md deleted file mode 100644 index 9e2f508dc5..0000000000 --- a/examples/hello/input.md +++ /dev/null @@ -1,31 +0,0 @@ -This is the source code of the traditional Hello World program. - -{hello.play} - -`println!` is a [*macro*][macros] that prints text to the -console. - -A binary can be generated using the Rust compiler: `rustc`. - -``` -$ rustc hello.rs -``` - -`rustc` will produce a `hello` binary that can be executed. - -``` -$ ./hello -Hello World! -``` - -### Activity - -Click 'Run' above to see the expected output. Next, add a new -line with a second `println!` macro so that the output -shows: -``` -Hello World! -I'm a Rustacean! -``` - -[macros]: ./macros.html diff --git a/examples/hello/print/fmt/show.rs b/examples/hello/print/fmt/show.rs deleted file mode 100644 index d616b1c481..0000000000 --- a/examples/hello/print/fmt/show.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::fmt::{self, Formatter, Display}; - -struct City { - name: &'static str, - // Latitude - lat: f32, - // Longitude - lon: f32, -} - -impl Display for City { - // `f` is a buffer, this method must write the formatted string into it - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; - let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' }; - - // `write!` is like `format!`, but it will write the formatted string - // into a buffer (the first argument) - write!(f, "{}: {:.3}°{} {:.3}°{}", - self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c) - } -} - -#[derive(Debug)] -struct Color { - red: u8, - green: u8, - blue: u8, -} - -fn main() { - for city in [ - City { name: "Dublin", lat: 53.347778, lon: -6.259722 }, - City { name: "Oslo", lat: 59.95, lon: 10.75 }, - City { name: "Vancouver", lat: 49.25, lon: -123.1 }, - ].iter() { - println!("{}", *city); - } - for color in [ - Color { red: 128, green: 255, blue: 90 }, - Color { red: 0, green: 3, blue: 254 }, - Color { red: 0, green: 0, blue: 0 }, - ].iter() { - // Switch this to use {} once you've added an implementation - // for fmt::Display - println!("{:?}", *color) - } -} diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md deleted file mode 100644 index b26f492a1f..0000000000 --- a/examples/hello/print/input.md +++ /dev/null @@ -1,42 +0,0 @@ -Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt] -some of which include: - -* `format!`: write formatted text to [`String`][string] -* `print!`: same as `format!` but the text is printed to the console. -* `println!`: same as `print!` but a newline is appended. - -All parse text in the same fashion. A plus is that the formatting correctness will -be checked at compile time. - -{print.play} - -[`std::fmt`][fmt] contains many [`traits`][traits] which govern the display -of text. The base form of two important ones are listed below: - -* `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes. -* `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user -friendly fashion. - -Here, `fmt::Display` was used because the std library provides implementations -for these types. To print text for custom types, more steps are required. - -### Activities - - * Fix the two issues in the above code (see FIXME) so that it runs without - error. - * Add a `println!` macro that prints: `Pi is roughly 3.142` by controlling - the number of decimal places shown. For the purposes of this exercise, - use `let pi = 3.141592` as an estimate for Pi. (Hint: you may need to - check the [`std::fmt`][fmt] documentation for setting the number of - decimals to display) - -### See also - -[`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], -and [`traits`][traits] - -[fmt]: https://doc.rust-lang.org/std/fmt/ -[macros]: /macros.html -[string]: /std/str.html -[structs]: /custom_types/structs.html -[traits]: /trait.html diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs deleted file mode 100644 index 6dfe4c011d..0000000000 --- a/examples/hello/print/print.rs +++ /dev/null @@ -1,42 +0,0 @@ -fn main() { - // In general, the `{}` will be automatically replaced with any - // arguments. These will be stringified. - println!("{} days", 31); - - // Without a suffix, 31 becomes an i32. You can change what type 31 is, - // with a suffix. - - // There are various optional patterns this works with. Positional - // arguments can be used. - println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); - - // As can named arguments. - println!("{subject} {verb} {object}", - object="the lazy dog", - subject="the quick brown fox", - verb="jumps over"); - - // Special formatting can be specified after a `:`. - println!("{} of {:b} people know binary, the other half doesn't", 1, 2); - - // You can right-align text with a specified width. This will output - // " 1". 5 white spaces and a "1". - println!("{number:>width$}", number=1, width=6); - - // You can pad numbers with extra zeroes. This will output "000001". - println!("{number:>0width$}", number=1, width=6); - - // It will even check to make sure the correct number of arguments are - // used. - println!("My name is {0}, {1} {0}", "Bond"); - // FIXME ^ Add the missing argument: "James" - - // Create a structure which contains an `i32`. Name it `Structure`. - #[allow(dead_code)] - struct Structure(i32); - - // However, custom types such as this structure require more complicated - // handling. This will not work. - println!("This struct `{}` won't print...", Structure(3)); - // FIXME ^ Comment out this line. -} diff --git a/examples/hello/print/print_debug/debug.rs b/examples/hello/print/print_debug/debug.rs deleted file mode 100644 index adcf278214..0000000000 --- a/examples/hello/print/print_debug/debug.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Derive the `fmt::Debug` implementation for `Structure`. `Structure` -// is a structure which contains a single `i32`. -#[derive(Debug)] -struct Structure(i32); - -// Put a `Structure` inside of the structure `Deep`. Make it printable -// also. -#[derive(Debug)] -struct Deep(Structure); - -fn main() { - // Printing with `{:?}` is similar to with `{}`. - println!("{:?} months in a year.", 12); - println!("{1:?} {0:?} is the {actor:?} name.", - "Slater", - "Christian", - actor="actor's"); - - // `Structure` is printable! - println!("Now {:?} will print!", Structure(3)); - - // The problem with `derive` is there is no control over how - // the results look. What if I want this to just show a `7`? - println!("Now {:?} will print!", Deep(Structure(7))); -} diff --git a/examples/hello/print/print_display/display.rs b/examples/hello/print/print_display/display.rs deleted file mode 100644 index 05df72c8f3..0000000000 --- a/examples/hello/print/print_display/display.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::fmt; // Import `fmt` - -// A structure holding two numbers. `Debug` will be derived so the results can -// be contrasted with `Display`. -#[derive(Debug)] -struct MinMax(i64, i64); - -// Implement `Display` for `MinMax`. -impl fmt::Display for MinMax { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Use `self.number` to refer to each positional data point. - write!(f, "({}, {})", self.0, self.1) - } -} - -// Define a structure where the fields are nameable for comparison. -#[derive(Debug)] -struct Point2D { - x: f64, - y: f64, -} - -// Similarly, implement for Point2D -impl fmt::Display for Point2D { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Customize so only `x` and `y` are denoted. - write!(f, "x: {}, y: {}", self.x, self.y) - } -} - -fn main() { - let minmax = MinMax(0, 14); - - println!("Compare structures:"); - println!("Display: {}", minmax); - println!("Debug: {:?}", minmax); - - let big_range = MinMax(-300, 300); - let small_range = MinMax(-3, 3); - - println!("The big range is {big} and the small is {small}", - small = small_range, - big = big_range); - - let point = Point2D { x: 3.3, y: 7.2 }; - - println!("Compare points:"); - println!("Display: {}", point); - println!("Debug: {:?}", point); - - // Error. Both `Debug` and `Display` were implemented but `{:b}` - // requires `fmt::Binary` to be implemented. This will not work. - // println!("What does Point2D look like in binary: {:b}?", point); -} diff --git a/examples/hello/print/print_display/testcase_list/testcase_list.rs b/examples/hello/print/print_display/testcase_list/testcase_list.rs deleted file mode 100644 index 20e6106642..0000000000 --- a/examples/hello/print/print_display/testcase_list/testcase_list.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::fmt; // Import the `fmt` module. - -// Define a structure named `List` containing a `Vec`. -struct List(Vec); - -impl fmt::Display for List { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Extract the value using tuple indexing - // and create a reference to `vec`. - let vec = &self.0; - - write!(f, "[")?; - - // Iterate over `vec` in `v` while enumerating the iteration - // count in `count`. - for (count, v) in vec.iter().enumerate() { - // For every element except the first, add a comma. - // Use the ? operator, or try!, to return on errors. - if count != 0 { write!(f, ", ")?; } - write!(f, "{}", v)?; - } - - // Close the opened bracket and return a fmt::Result value - write!(f, "]") - } -} - -fn main() { - let v = List(vec![1, 2, 3]); - println!("{}", v); -} diff --git a/fix-edit-button.sh b/fix-edit-button.sh deleted file mode 100755 index 0c3baefaa0..0000000000 --- a/fix-edit-button.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -for example in $(find examples -type d -name "*"); do - html=stage/_book/${example#examples/}.html - if [[ -f ${html} ]]; then - echo ${html} - - sed -i -e s:${example#examples/}.md:${example}/input.md: ${html} - fi -done diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css deleted file mode 100644 index 697a913ca5..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ /dev/null @@ -1,87 +0,0 @@ -/* the style here follows graydon/rust-www */ - -#active-code { - position: relative; - display: block; - padding: 10px; - border-radius: 4px; - background-color: #FDFDFD; - border: 1px solid #CCC; - margin-bottom: 16px; -} - -#editor { - padding: none; - margin: none; - width: 100%; - min-height: 72px; - font-size: 13px; - font-family: Menlo, Monaco, Consolas, monospace; - white-space: pre-wrap; -} - -#result { - color: #333; - background-color: #E2EEF6; - margin-top: 10px; - padding: 10px; - display: none; - border-radius: 4px; - font-family: Menlo, Monaco, Consolas, monospace; - white-space: pre-wrap; -} - -#reset-code { - position: absolute; - z-index: 10; - float: right; - right: 8px; - top: 50px; - outline: none; -} - -#run-code { - position: absolute; - z-index: 10; - float: right; - right: 8px; - top: 8px; - outline: none; -} - -.ace-error-text, .ace-error-line, .ace-warning-text, .ace-warning-line { - position: absolute; -} - -.ace-error-text { - background-color: #e9abab; -} - -.ace-error-line { - background-color: #F6E2E2; -} - -.ace-warning-text { - background-color: #FFEF00; -} - -.ace-warning-line { - background-color: #FFFBCB; -} - -.btn-primary { - color: #fff; - background-color: #428bca; - border-color: #357ebd; - border-radius: 4px; -} -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active { - color: #fff; - background-color: #3276b1; - border-color: #285e8e; -} -.btn-primary:active { - background-image: none; -} diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js deleted file mode 100644 index ea0bbd34fa..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ /dev/null @@ -1,298 +0,0 @@ -// this is mostly the editor implemented by @SergioBenitez for graydon/rust-www -// plus small modifications to accommodate a "Reset" button - -// ECMAScript 6 Backwards compatability -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function(str) { - return this.slice(0, str.length) == str; - }; -} - -// Regex for finding new lines -var newLineRegex = /(?:\r\n|\r|\n)/g; - -// DOM items -var editorDiv; -var resetButton; -var runButton; -var resultDiv; - -// Background colors for program result on success/error -var successColor = "#E2EEF6"; -var errorColor = "#F6E2E2"; -var warningColor = "#FFFBCB"; - -// Error message to return when there's a server failure -var errMsg = "The server encountered an error while running the program."; - -// Stores ACE editor markers (highights) for errors -var markers = []; - -// Status codes, because there are no enums in Javascript -var SUCCESS = 0; -var ERROR = 1; -var WARNING = 2; - -// Ace editor -var editor; -var Range; - -// Original source code -var originalCode; - -// Maximum length of a response before it has to be truncated -var MAX_RESPONSE_LENGTH = 50000; - -function initEditor() { - // Fetching DOM items - editorDiv = document.getElementById("editor"); - resetButton = document.getElementById("reset-code"); - runButton = document.getElementById("run-code"); - resultDiv = document.getElementById("result"); - - if (editorDiv === null) - return; // No editor on this page - - // Setup ace editor - editor = ace.edit("editor"); - Range = ace.require('ace/range').Range; - - var executeCode = function(ev) { - resultDiv.style.display = "block"; - resultDiv.innerHTML = "Running..."; - resultDiv.scrollIntoView(); - - // Clear previous markers, if any - markers.map(function(id) { editor.getSession().removeMarker(id); }); - - // Get the code, run the program - var program = editor.getValue(); - runProgram(program, handleResult); - }; - - ace.config.setModuleUrl('ace/mode/rust', '/gitbook/plugins/gitbook-plugin-rust-playpen/mode-rust.js'); - - editor.setTheme("ace/theme/tomorrow"); - editor.getSession().setMode("ace/mode/rust"); - editor.setShowPrintMargin(false); - editor.renderer.setShowGutter(false); - editor.setHighlightActiveLine(false); - editor.commands.addCommand({ - name: "run", - bindKey: { - win: "Ctrl-Enter", - mac: "Ctrl-Enter" - }, - exec: executeCode - }) - - originalCode = editor.getSession().getValue(); - - // Set initial size to match initial content - updateEditorHeight(); - - // Registering handler for run button click - runButton.addEventListener("click", executeCode); - - // Registering handler for reset button click - resetButton.addEventListener("click", function(ev) { - // Clear previous markers, if any - markers.map(function(id) { editor.getSession().removeMarker(id); }); - - editor.getSession().setValue(originalCode); - resultDiv.style.display = "none"; - }); - - editor.on('change', updateEditorHeight); - - // Highlight active line when focused - editor.on('focus', function() { - editor.setHighlightActiveLine(true); - }); - - // Don't when not - editor.on('blur', function() { - editor.setHighlightActiveLine(false); - }); -} - -require(["gitbook"], function(gitbook) { - gitbook.events.bind("page.change", function() { - initEditor(); - }) -}); - -// Changes the height of the editor to match its contents -function updateEditorHeight() { - // http://stackoverflow.com/questions/11584061/ - var newHeight = editor.getSession().getScreenLength() - * editor.renderer.lineHeight - + editor.renderer.scrollBar.getWidth(); - - editorDiv.style.height = Math.ceil(newHeight).toString() + "px"; - editor.resize(); -}; - -// -// escapeHTML() borrowed from mustache.js: -// https://github.com/janl/mustache.js/blob/master/mustache.js#L43 -// -// via: -// http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery/12034334#12034334 -// -var entityMap = { - "&": "&", - "<": "<", - ">": ">", - '"': '"', - "'": ''', - "/": '/' -}; - -function escapeHTML(unsafe) { - return String(unsafe).replace(/[&<>"'\/]/g, function(s) { - return entityMap[s]; - }); -} - -// Dispatches a XMLHttpRequest to the Rust playpen, running the program, and -// issues a callback to `callback` with the result (or null on error) -function runProgram(program, callback) { - var req = new XMLHttpRequest(); - var data = JSON.stringify({ - version: "stable", - optimize: "0", - code: program - }); - - // console.log("Sending", data); - req.open('POST', "https://play.rust-lang.org/evaluate.json", true); - req.onload = function(e) { - if (req.readyState === 4 && req.status === 200) { - var result = JSON.parse(req.response).result; - - // Need server support to get an accurate version of this. - var statusCode = SUCCESS; - if (result.indexOf("error:") !== -1) { - statusCode = ERROR; - } else if (result.indexOf("warning:") !== -1) { - statusCode = WARNING; - } - - callback(statusCode, result); - } else { - callback(false, null); - } - }; - - req.onerror = function(e) { - callback(false, null); - } - - req.setRequestHeader("Content-Type", "application/json"); - req.send(data); -} - -// The callback to runProgram -function handleResult(statusCode, message) { - - // Check the size of the message, shorten it if - // it's too big to be appended to the DOM. - if ( message.length > MAX_RESPONSE_LENGTH ) { - message = message.slice(0, MAX_RESPONSE_LENGTH / 2) - + '\n\n--- THIS RESULT HAS BEEN SHORTENED ---\n\n' - + message.slice(-MAX_RESPONSE_LENGTH / 2); - } - - // Dispatch depending on result type - if (result == null) { - resultDiv.style.backgroundColor = errorColor; - resultDiv.innerHTML = errMsg; - } else if (statusCode == SUCCESS) { - handleSuccess(message); - } else if (statusCode == WARNING) { - handleWarning(message); - } else { - handleError(message); - } -} - -// Called on successful program run -function handleSuccess(message) { - resultDiv.style.backgroundColor = successColor; - var lines = message.split(newLineRegex); - message = lines.map(function(line) { - return escapeHTML(line); - }).join('
'); - resultDiv.innerHTML = message; -} - -// Called when program run results in warning(s) -function handleWarning(message) { - resultDiv.style.backgroundColor = warningColor; - handleProblem(message, "warning"); -} - -// Called when program run results in error(s) -function handleError(message) { - resultDiv.style.backgroundColor = errorColor; - handleProblem(message, "error"); -} - -// Called on unsuccessful program run. Detects and prints problems (either -// warnings or errors) in program output and highlights relevant lines and text -// in the code. -function handleProblem(message, problem) { - // Getting list of ranges with problems - var lines = message.split(newLineRegex); - - // Cleaning up the message: keeps only relevant problem output - var cleanMessage = lines.map(function(line) { - if (line.startsWith("") || line.indexOf("^") !== -1) { - var errIndex = line.indexOf(problem + ": "); - if (errIndex !== -1) return line.slice(errIndex); - return ""; - } - - // Discard playpen messages, keep the rest - if (line.startsWith("playpen:")) return ""; - return line; - }).filter(function(line) { - return line !== ""; - }).map(function(line) { - return escapeHTML(line); - }).join("
"); - - // Setting message - resultDiv.innerHTML = cleanMessage; - - // Highlighting the lines - var ranges = parseProblems(lines); - markers = ranges.map(function(range) { - return editor.getSession().addMarker(range, "ace-" + problem + "-line", - "fullLine", false); - }); - - // Highlighting the specific text - markers = markers.concat(ranges.map(function(range) { - return editor.getSession().addMarker(range, "ace-" + problem + "-text", - "text", false); - })); -} - -// Parses a problem message returning a list of ranges (row:col, row:col) where -// problems in the code have occured. -function parseProblems(lines) { - var ranges = []; - for (var i in lines) { - var line = lines[i]; - if (line.startsWith(":") && line.indexOf(": ") !== -1) { - var parts = line.split(/:\s?|\s+/, 5).slice(1, 5); - var ip = parts.map(function(p) { return parseInt(p, 10) - 1; }); - // console.log("line:", line, parts, ip); - ranges.push(new Range(ip[0], ip[1], ip[2], ip[3])); - } - } - - return ranges; -} diff --git a/node_modules/gitbook-plugin-rust-playpen/index.js b/node_modules/gitbook-plugin-rust-playpen/index.js deleted file mode 100644 index bbaa5b886c..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/index.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - book: { - assets: "./book", - css: [ - "editor.css" - ], - js: [ - "ace/ace.js", - "editor.js", - "mode-rust.js" - ] - } -}; diff --git a/node_modules/gitbook-plugin-rust-playpen/package.json b/node_modules/gitbook-plugin-rust-playpen/package.json deleted file mode 100644 index 34040733f9..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Integrate Rust playpen with gitbook", - "engines": { - "gitbook": "*" - }, - "main": "index.js", - "name": "gitbook-plugin-rust-playpen" -} diff --git a/setup-stage.sh b/setup-stage.sh deleted file mode 100755 index 8d02ed3ff9..0000000000 --- a/setup-stage.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min' -ace_playpen_local='node_modules/gitbook-plugin-rust-playpen' - -mkdir -p bin -mkdir -p stage/node_modules -svn checkout ${ace_repository} ${ace_playpen_local}'/book/ace' -cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' - -ln -sf ../book.json stage -ln -sf ../examples/README.md stage diff --git a/src/SUMMARY.md b/src/SUMMARY.md new file mode 100644 index 0000000000..21d005750e --- /dev/null +++ b/src/SUMMARY.md @@ -0,0 +1,11 @@ +# Summary + +[Introduction](index.md) + +- [Hello World](hello.md) + - [Comments](hello/comment.md) + - [Formatted print](hello/print.md) + - [Debug](hello/print/print_debug.md) + - [Display](hello/print/print_display.md) + - [Testcase: List](hello/print/print_display/testcase_list.md) + - [Formatting](hello/print/fmt.md) diff --git a/src/example.rs b/src/example.rs deleted file mode 100644 index c5918ca0a4..0000000000 --- a/src/example.rs +++ /dev/null @@ -1,104 +0,0 @@ -use markdown::Markdown; -use rustc_serialize::{Decodable,json}; -use std::iter::repeat; -use std::sync::mpsc; -use std::io::prelude::*; -use std::fs; -use std::fs::File; -use std::path::Path; - -#[derive(RustcDecodable)] -pub struct Example { - children: Option>, - id: String, - title: String, -} - -impl Example { - pub fn get_list() -> Vec { - - let mut f = File::open(&Path::new("examples/structure.json")).unwrap(); - let mut s = String::new(); - f.read_to_string(&mut s).unwrap(); - - match json::Json::from_str(&s) { - Err(_) => panic!("structure.json is not valid json"), - Ok(json) => { - match Decodable::decode(&mut json::Decoder::new(json)) { - Err(_) => panic!("error decoding structure.json"), - Ok(examples) => examples, - } - } - } - } - - pub fn count(&self) -> usize { - match self.children { - None => 1, - Some(ref children) => 1 + children.iter() - .map(|c| c.count()) - .fold(0, |sum, i| sum + i), - } - } - - pub fn process(&self, - number: Vec, - tx: mpsc::Sender<(Vec, String)>, - indent: usize, - prefix: String) - { - let id = &self.id; - let prefix = &prefix; - let title = &self.title; - - let entry = - match Markdown::process(&number, id, title, prefix) { - Ok(_) => { - let md = if prefix.chars().all(|c| c.is_whitespace()) { - format!("{}.md", id) - } else { - format!("{}/{}.md", prefix, id) - }; - - format!("{}* [{}]({})", - repeat(" ").take(indent).collect::(), - title, - md) - }, - Err(why) => { - print!("{}: {}\n", id, why); - format!("{}* {}", - repeat(" ").take(indent).collect::(), - title) - }, - }; - - let _ = tx.send((number.clone(), entry)); - - match self.children { - None => {}, - Some(ref children) => { - let path_str = &format!("stage/{}/{}", prefix, id); - let path = Path::new(path_str); - - fs::create_dir_all(&path).unwrap(); - - for (i, example) in children.iter().enumerate() { - let tx = tx.clone(); - let prefix = if prefix.chars().all(|c| c.is_whitespace()) { - format!("{}", id) - } else { - format!("{}/{}", prefix, id) - }; - - let mut number = number.clone(); - number.push(i + 1); - example.process(number, - tx, - indent + 1, - prefix); - } - }, - } - } -} diff --git a/src/file.rs b/src/file.rs deleted file mode 100644 index adb918c70e..0000000000 --- a/src/file.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow(deprecated)] - -use std::env; -use std::process::Command; -use std::io::prelude::*; -use std::io; -use std::fs; -use std::fs::File; -use std::path::Path; - -pub fn mkdir(path: &Path) { - match fs::create_dir_all(path) { - Err(_) => {}, - Ok(_) => {}, - } -} - -pub fn run(prefix: &str, id: &str, src: &str) -> Result { - let cwd = env::current_dir().unwrap(); - // Assume that the current working directory actually exists - let out_dir = cwd.join(&format!("bin/{}/{}", prefix, id)); - let path_str = &format!("examples/{}/{}", prefix, id); - - match Command::new("rustc") - .current_dir(&Path::new(path_str)) - .arg(&format!("{}.rs", src)) - .arg("--out-dir") - .arg(&out_dir) - .output() { - Ok(o) => o, - Err(e) => { return Ok(e.to_string()) }, - }; - - let exec_str = &format!("./bin/{}/{}/{}", prefix, id, src); - let executable = Path::new(exec_str); - - let output = match Command::new(&executable).output() { - Ok(o) => o, - Err(e) => { return Ok(e.to_string()) }, - }; - - Ok(String::from_utf8(output.stdout).unwrap()) -} - -pub fn write(path: &Path, string: &str) -> io::Result<()> { - let mut f = try!(File::create(path)); - f.write_all(string.as_bytes()) -} diff --git a/src/hello.md b/src/hello.md new file mode 100644 index 0000000000..87df4027b4 --- /dev/null +++ b/src/hello.md @@ -0,0 +1,49 @@ +# Hello World + +This is the source code of the traditional Hello World program. + +```rust,editable +// This is a comment, and will be ignored by the compiler +// You can test this code by clicking the "Run" button over there -> +// or if prefer to use your keyboard, you can use the "Ctrl + Enter" shortcut + +// This code is editable, feel free to hack it! +// You can always return to the original code by clicking the "Reset" button -> + +// This is the main function +fn main() { + // The statements here will be executed when the compiled binary is called + + // Print text to the console + println!("Hello World!"); +} +``` + +`println!` is a [*macro*][macros] that prints text to the +console. + +A binary can be generated using the Rust compiler: `rustc`. + +```bash +$ rustc hello.rs +``` + +`rustc` will produce a `hello` binary that can be executed. + +```bash +$ ./hello +Hello World! +``` + +### Activity + +Click 'Run' above to see the expected output. Next, add a new +line with a second `println!` macro so that the output +shows: + +```text +Hello World! +I'm a Rustacean! +``` + +[macros]: ./macros.html diff --git a/examples/hello/comment/comment.rs b/src/hello/comment.md similarity index 66% rename from examples/hello/comment/comment.rs rename to src/hello/comment.md index 15a4c4d0ad..f88d02fcf8 100644 --- a/examples/hello/comment/comment.rs +++ b/src/hello/comment.md @@ -1,3 +1,17 @@ +# Comments + +Any program requires comments and indeed Rust supports +a few different varieties: + +* *Regular comments* which are ignored by the compiler: + - `// Line comments which go to the end of the line.` + - `/* Block comments which go to the closing delimiter. */` +* *Doc comments* which are parsed into HTML library +[documentation][docs]: + - `/// Generate library docs for the following item.` + - `//! Generate library docs for the enclosing item.` + +```rust,editable fn main() { // This is an example of a line comment // Notice how there are two slashes at the beginning of the line @@ -27,3 +41,11 @@ fn main() { let x = 5 + /* 90 + */ 5; println!("Is `x` 10 or 100? x = {}", x); } + +``` + +### See also: + +[Library documentation][docs] + +[docs]: /meta/doc.html diff --git a/src/hello/print.md b/src/hello/print.md new file mode 100644 index 0000000000..6dae4d7037 --- /dev/null +++ b/src/hello/print.md @@ -0,0 +1,87 @@ +# Formatted print + +Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt] +some of which include: + +* `format!`: write formatted text to [`String`][string] +* `print!`: same as `format!` but the text is printed to the console. +* `println!`: same as `print!` but a newline is appended. + +All parse text in the same fashion. A plus is that the formatting correctness will +be checked at compile time. + +```rust,editable +fn main() { + // In general, the `{}` will be automatically replaced with any + // arguments. These will be stringified. + println!("{} days", 31); + + // Without a suffix, 31 becomes an i32. You can change what type 31 is, + // with a suffix. + + // There are various optional patterns this works with. Positional + // arguments can be used. + println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); + + // As can named arguments. + println!("{subject} {verb} {object}", + object="the lazy dog", + subject="the quick brown fox", + verb="jumps over"); + + // Special formatting can be specified after a `:`. + println!("{} of {:b} people know binary, the other half doesn't", 1, 2); + + // You can right-align text with a specified width. This will output + // " 1". 5 white spaces and a "1". + println!("{number:>width$}", number=1, width=6); + + // You can pad numbers with extra zeroes. This will output "000001". + println!("{number:>0width$}", number=1, width=6); + + // It will even check to make sure the correct number of arguments are + // used. + println!("My name is {0}, {1} {0}", "Bond"); + // FIXME ^ Add the missing argument: "James" + + // Create a structure which contains an `i32`. Name it `Structure`. + #[allow(dead_code)] + struct Structure(i32); + + // However, custom types such as this structure require more complicated + // handling. This will not work. + println!("This struct `{}` won't print...", Structure(3)); + // FIXME ^ Comment out this line. +} +``` + +[`std::fmt`][fmt] contains many [`traits`][traits] which govern the display +of text. The base form of two important ones are listed below: + +* `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes. +* `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user +friendly fashion. + +Here, `fmt::Display` was used because the std library provides implementations +for these types. To print text for custom types, more steps are required. + +### Activities + + * Fix the two issues in the above code (see FIXME) so that it runs without + error. + * Add a `println!` macro that prints: `Pi is roughly 3.142` by controlling + the number of decimal places shown. For the purposes of this exercise, + use `let pi = 3.141592` as an estimate for Pi. (Hint: you may need to + check the [`std::fmt`][fmt] documentation for setting the number of + decimals to display) + +### See also + +[`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], +and [`traits`][traits] + +[fmt]: https://doc.rust-lang.org/std/fmt/ +[macros]: /macros.html +[string]: /std/str.html +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/examples/hello/print/fmt/input.md b/src/hello/print/fmt.md similarity index 50% rename from examples/hello/print/fmt/input.md rename to src/hello/print/fmt.md index 2635cc4a28..4a38dab0f8 100644 --- a/examples/hello/print/fmt/input.md +++ b/src/hello/print/fmt.md @@ -1,3 +1,5 @@ +# Formatting + We've seen that formatting is specified via a *format string*: * `format!("{}", foo)` -> `"3735928559"` @@ -12,7 +14,56 @@ This formatting functionality is implemented via traits, and there is one trait for each argument type. The most common formatting trait is `Display`, which handles cases where the argument type is left unspecified: `{}` for instance. -{show.play} +```rust,editable +use std::fmt::{self, Formatter, Display}; + +struct City { + name: &'static str, + // Latitude + lat: f32, + // Longitude + lon: f32, +} + +impl Display for City { + // `f` is a buffer, this method must write the formatted string into it + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; + let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' }; + + // `write!` is like `format!`, but it will write the formatted string + // into a buffer (the first argument) + write!(f, "{}: {:.3}°{} {:.3}°{}", + self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c) + } +} + +#[derive(Debug)] +struct Color { + red: u8, + green: u8, + blue: u8, +} + +fn main() { + for city in [ + City { name: "Dublin", lat: 53.347778, lon: -6.259722 }, + City { name: "Oslo", lat: 59.95, lon: 10.75 }, + City { name: "Vancouver", lat: 49.25, lon: -123.1 }, + ].iter() { + println!("{}", *city); + } + for color in [ + Color { red: 128, green: 255, blue: 90 }, + Color { red: 0, green: 3, blue: 254 }, + Color { red: 0, green: 0, blue: 0 }, + ].iter() { + // Switch this to use {} once you've added an implementation + // for fmt::Display + println!("{:?}", *color) + } +} +``` You can view a [full list of formatting traits][fmt_traits] and their argument types in the [`std::fmt`][fmt] documentation. @@ -26,11 +77,13 @@ RGB (128, 255, 90) 0x80FF5A RGB (0, 3, 254) 0x0003FE RGB (0, 0, 0) 0x000000 ``` + Two hints if you get stuck: * You [may need to list each color more than once][argument_types], * You can [pad with zeros to a width of 2][fmt_width] with `:02`. ### See also + [`std::fmt`][fmt] [argument_types]: https://doc.rust-lang.org/std/fmt/#argument-types diff --git a/examples/hello/print/print_debug/input.md b/src/hello/print/print_debug.md similarity index 59% rename from examples/hello/print/print_debug/input.md rename to src/hello/print/print_debug.md index de5d5baef3..b157596fed 100644 --- a/examples/hello/print/print_debug/input.md +++ b/src/hello/print/print_debug.md @@ -1,3 +1,5 @@ +# Debug + All types which want to use `std::fmt` formatting `traits` require an implementation to be printable. Automatic implementations are only provided for types such as in the `std` library. All others *must* be manually @@ -20,7 +22,33 @@ struct DebugPrintable(i32); All `std` library types automatically are printable with `{:?}` too: -{debug.play} +```rust,editible +// Derive the `fmt::Debug` implementation for `Structure`. `Structure` +// is a structure which contains a single `i32`. +#[derive(Debug)] +struct Structure(i32); + +// Put a `Structure` inside of the structure `Deep`. Make it printable +// also. +#[derive(Debug)] +struct Deep(Structure); + +fn main() { + // Printing with `{:?}` is similar to with `{}`. + println!("{:?} months in a year.", 12); + println!("{1:?} {0:?} is the {actor:?} name.", + "Slater", + "Christian", + actor="actor's"); + + // `Structure` is printable! + println!("Now {:?} will print!", Structure(3)); + + // The problem with `derive` is there is no control over how + // the results look. What if I want this to just show a `7`? + println!("Now {:?} will print!", Deep(Structure(7))); +} +``` So `fmt::Debug` definitely makes this printable but sacrifices some elegance. Manually implementing `fmt::Display` will fix that. diff --git a/examples/hello/print/print_display/input.md b/src/hello/print/print_display.md similarity index 62% rename from examples/hello/print/print_display/input.md rename to src/hello/print/print_display.md index 0be56ab081..264b6d5e95 100644 --- a/examples/hello/print/print_display/input.md +++ b/src/hello/print/print_display.md @@ -1,3 +1,5 @@ +# Display + `fmt::Debug` hardly looks compact and clean, so it is often advantageous to customize the output appearance. This is done by manually implementing [`fmt::Display`][fmt], which uses the `{}` print marker. Implementing it @@ -41,7 +43,62 @@ generic cases. This is not a problem though because for any new *container* type which is *not* generic,`fmt::Display` can be implemented. -{display.play} +```rust,editable +use std::fmt; // Import `fmt` + +// A structure holding two numbers. `Debug` will be derived so the results can +// be contrasted with `Display`. +#[derive(Debug)] +struct MinMax(i64, i64); + +// Implement `Display` for `MinMax`. +impl fmt::Display for MinMax { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Use `self.number` to refer to each positional data point. + write!(f, "({}, {})", self.0, self.1) + } +} + +// Define a structure where the fields are nameable for comparison. +#[derive(Debug)] +struct Point2D { + x: f64, + y: f64, +} + +// Similarly, implement for Point2D +impl fmt::Display for Point2D { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Customize so only `x` and `y` are denoted. + write!(f, "x: {}, y: {}", self.x, self.y) + } +} + +fn main() { + let minmax = MinMax(0, 14); + + println!("Compare structures:"); + println!("Display: {}", minmax); + println!("Debug: {:?}", minmax); + + let big_range = MinMax(-300, 300); + let small_range = MinMax(-3, 3); + + println!("The big range is {big} and the small is {small}", + small = small_range, + big = big_range); + + let point = Point2D { x: 3.3, y: 7.2 }; + + println!("Compare points:"); + println!("Display: {}", point); + println!("Debug: {:?}", point); + + // Error. Both `Debug` and `Display` were implemented but `{:b}` + // requires `fmt::Binary` to be implemented. This will not work. + // println!("What does Point2D look like in binary: {:b}?", point); +} +``` So, `fmt::Display` has been implemented but `fmt::Binary` has not, and therefore cannot be used. `std::fmt` has many such [`traits`][traits] and diff --git a/examples/hello/print/print_display/testcase_list/input.md b/src/hello/print/print_display/testcase_list.md similarity index 55% rename from examples/hello/print/print_display/testcase_list/input.md rename to src/hello/print/print_display/testcase_list.md index 5e56c3348b..52dab44b2b 100644 --- a/examples/hello/print/print_display/testcase_list/input.md +++ b/src/hello/print/print_display/testcase_list.md @@ -1,3 +1,5 @@ +# Testcase: List + Implementing `fmt::Display` for a structure where the elements must each be handled sequentially is tricky. The problem is that each `write!` generates a `fmt::Result`. Proper handling of this requires dealing with *all* the @@ -21,7 +23,39 @@ write!(f, "{}", value)?; With `?` available, implementing `fmt::Display` for a `Vec` is straightforward: -{testcase_list.play} +```rust,editable +use std::fmt; // Import the `fmt` module. + +// Define a structure named `List` containing a `Vec`. +struct List(Vec); + +impl fmt::Display for List { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Extract the value using tuple indexing + // and create a reference to `vec`. + let vec = &self.0; + + write!(f, "[")?; + + // Iterate over `vec` in `v` while enumerating the iteration + // count in `count`. + for (count, v) in vec.iter().enumerate() { + // For every element except the first, add a comma. + // Use the ? operator, or try!, to return on errors. + if count != 0 { write!(f, ", ")?; } + write!(f, "{}", v)?; + } + + // Close the opened bracket and return a fmt::Result value + write!(f, "]") + } +} + +fn main() { + let v = List(vec![1, 2, 3]); + println!("{}", v); +} +``` ### Activity @@ -31,7 +65,6 @@ Try changing the program so that the index of each element in the vector is also [0: 1, 1: 2, 2: 3] ``` - ### See also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], diff --git a/src/index.md b/src/index.md new file mode 100644 index 0000000000..e10b99d013 --- /dev/null +++ b/src/index.md @@ -0,0 +1 @@ +# Introduction diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 54f7ea1d0e..0000000000 --- a/src/main.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![deny(warnings)] -#![allow(deprecated)] - -extern crate regex; -extern crate rustc_serialize; - -use example::Example; -use std::thread; -use std::sync::mpsc; -use std::path::Path; - -mod example; -mod file; -mod markdown; -mod playpen; - -fn main() { - let examples = Example::get_list(); - let (tx, rx) = mpsc::channel(); - let mut children = vec![]; - - let mut nexamples = 0; - for (i, example) in examples.into_iter().enumerate() { - let tx = tx.clone(); - let count = example.count(); - - children.push(thread::spawn(move || { - example.process(vec!(i + 1), tx, 0, String::new()); - })); - - nexamples += count; - } - - for child in children { let _ = child.join(); } - - let mut entries = (0..nexamples).map(|_| { - rx.recv().unwrap() - }).collect::, String)>>(); - - entries.sort_by(|&(ref i, _), &(ref j, _)| i.cmp(j)); - - let summary = entries.into_iter() - .map(|(_, s)| s) - .collect::>() - .connect("\n"); - - match file::write(&Path::new("stage/SUMMARY.md"), &summary) { - Err(why) => panic!("{}", why), - Ok(_) => {}, - } -} diff --git a/src/markdown.rs b/src/markdown.rs deleted file mode 100644 index 5ab916453b..0000000000 --- a/src/markdown.rs +++ /dev/null @@ -1,175 +0,0 @@ -use file; -use playpen; -use std::iter::repeat; -use regex::Regex; -use std::io::prelude::*; -use std::fs::File; -use std::path::Path; -use std::error::Error; - -pub struct Markdown<'a, 'b> { - content: String, - id: &'a str, - prefix: &'b str, -} - -impl<'a, 'b> Markdown<'a, 'b> { - pub fn process(number: &[usize], id: &'a str, title: &str, prefix: &'b str) - -> Result<(), String> - { - let mut mkd = try!(Markdown::new(number, id, title, prefix)); - - try!(mkd.insert_sources()); - try!(mkd.insert_outputs()); - try!(mkd.insert_playpen_links()); - try!(mkd.save()); - - Ok(()) - } - - fn new(number: &[usize], id: &'a str, title: &str, prefix: &'b str) - -> Result, String> - { - let path_str = &format!("examples/{}/{}/input.md", prefix, id); - let path = Path::new(path_str); - - let mut f = File::open(&path).unwrap(); - let mut body = String::new(); - f.read_to_string(&mut body).unwrap(); - - let version = number.iter().map(|x| { - format!("{}", x) - }).collect::>().connect("."); - - let len = number.len(); - let content = format!("{} {} {}\n\n{}", - repeat("#").take(len).collect::(), - version, - title, - body); - - Ok(Markdown { - content: content, - id: id, - prefix: prefix, - }) - } - - fn insert_sources(&mut self) -> Result<(), String> { - let id = self.id; - let prefix = self.prefix; - let re = Regex::new(r"\{(.*\.rs)\}").unwrap(); - - let mut table = Vec::new(); - for line in self.content.lines() { - match re.captures(line) { - None => {}, - Some(captures) => { - let src = captures.at(1).unwrap(); - let input = format!("{{{}}}", src); - let p = format!("examples/{}/{}/{}", prefix, id, src); - - let mut f = File::open(&Path::new(&p)).unwrap(); - let mut s = String::new(); - f.read_to_string(&mut s).unwrap(); - let output = format!("``` rust\n// {}\n{}```", src, s); - - table.push((input, output)) - } - } - } - - for (input, output) in table.into_iter() { - self.content = self.content.replace(&input, - &output); - } - - Ok(()) - } - - fn insert_outputs(&mut self) -> Result<(), String> { - let id = self.id; - let prefix = self.prefix; - let r = Regex::new(r"\{(.*)\.out\}").unwrap(); - - let dir_str = &format!("bin/{}/{}", prefix, id); - let dir = Path::new(dir_str); - - file::mkdir(dir); - - let mut table = Vec::new(); - for line in self.content.lines() { - match r.captures(line) { - None => {}, - Some(captures) => { - let src = captures.at(1).unwrap(); - let input = format!("{{{}.out}}", src); - let s = try!(file::run(prefix, id, src)); - - let s = format!("``` \n\ - $ rustc {0}.rs && ./{0}\n{1}\n\ - ```", - src, s); - - table.push((input, s)); - }, - } - } - - for (input, output) in table.into_iter() { - self.content = self.content.replace(&input, - &output); - } - - Ok(()) - } - - fn insert_playpen_links(&mut self) -> Result<(), String> { - let id = self.id; - let prefix = self.prefix; - let re = Regex::new(r"\{(.*)\.play\}").unwrap(); - - let mut once_ = false; - let mut table = Vec::new(); - for line in self.content.lines() { - match re.captures(line) { - None => {}, - Some(captures) => { - if once_ { - return Err(format!("more than one editor!")) - } else { - once_ = true; - } - - let srcbase = captures.at(1).unwrap(); - let input = format!("{{{}.play}}", srcbase); - let src = format!("{}.rs", srcbase); - let p = format!("examples/{}/{}/{}", prefix, id, src); - - let mut f = File::open(&Path::new(&p)).unwrap(); - let mut s = String::new(); - f.read_to_string(&mut s).unwrap(); - - let output = playpen::editor(&s); - - table.push((input, output)) - } - } - } - - for (input, output) in table.into_iter() { - self.content = self.content.replace(&input, - &output); - } - - Ok(()) - } - - fn save(&self) -> Result<(), String> { - let path_str = &format!("stage/{}/{}.md", self.prefix, self.id); - let path = Path::new(path_str); - - file::write(&path, &self.content) - .map_err(|ref e| e.description().to_string()) - } -} diff --git a/src/playpen.rs b/src/playpen.rs deleted file mode 100644 index b211dfc0fa..0000000000 --- a/src/playpen.rs +++ /dev/null @@ -1,27 +0,0 @@ -pub fn editor(source: &str) -> String { - format!("
- - -
{}
-
-
", escape(source)) -} - -fn escape(source: &str) -> String { - let mut s = String::new(); - - for chr in source.trim().chars() { - match chr { - '$' => s.push_str("$"), - '*' => s.push_str("*"), - '<' => s.push_str("<"), - '>' => s.push_str(">"), - '\\' => s.push_str("\"), - '_' => s.push_str("_"), - '`' => s.push_str("`"), - chr => s.push(chr), - } - } - - s -} diff --git a/vendor/gitbook/jsrepl/engines/javascript-default.js b/vendor/gitbook/jsrepl/engines/javascript-default.js deleted file mode 100755 index b26c5c033f..0000000000 --- a/vendor/gitbook/jsrepl/engines/javascript-default.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - - Copyright Joyent, Inc. and other Node contributors. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - USE OR OTHER DEALINGS IN THE SOFTWARE. - - Original at: https://github.com/joyent/node/blob/master/lib/util.js -*/ -(function(){function o(c){return c instanceof Array||Array.isArray(c)||c&&c!==Object.prototype&&o(c.__proto__)}function p(c){return c instanceof RegExp||typeof c==="function"&&c.constructor.name==="RegExp"&&c.compile&&c.test&&c.exec&&(""+c).match(/^\/.*\/[gim]{0,3}$/)}var q=80,l=function(c,h,b,f){function m(a,c){switch(typeof a){case "undefined":return d("undefined","undefined");case "string":var b="'"+JSON.stringify(a).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return d(b,"string"); -case "number":return d(""+a,"number");case "boolean":return d(""+a,"boolean")}if(a===null)return d("null","null");var f=Object.keys(a),i=h?Object.getOwnPropertyNames(a):f;if(typeof a==="function"&&i.length===0)return p(a)?d(""+a,"regexp"):d("[Function"+(a.name?": "+a.name:"")+"]","special");if(a instanceof Date&&i.length===0)return d(a.toUTCString(),"date");var j,l;o(a)?(l="Array",b=["[","]"]):(l="Object",b=["{","}"]);typeof a==="function"?(j=a.name?": "+a.name:"",j=p(a)?" "+a:" [Function"+j+"]"): -j="";a instanceof Date&&(j=" "+a.toUTCString());if(i.length===0)return b[0]+j+b[1];if(c<0)return p(a)?d(""+a,"regexp"):d("[Object]","special");k.push(a);i=i.map(function(b){var e,g;a.__lookupGetter__&&(a.__lookupGetter__(b)?g=a.__lookupSetter__(b)?d("[Getter/Setter]","special"):d("[Getter]","special"):a.__lookupSetter__(b)&&(g=d("[Setter]","special")));f.indexOf(b)<0&&(e="["+b+"]");g||(k.indexOf(a[b])<0?(g=c===null?m(a[b]):m(a[b],c-1),g.indexOf("\n")>-1&&(g=o(a)?g.split("\n").map(function(a){return" "+ -a}).join("\n").substr(2):"\n"+g.split("\n").map(function(a){return" "+a}).join("\n"))):g=d("[Circular]","special"));if(typeof e==="undefined"){if(l==="Array"&&b.match(/^\d+$/))return g;e=JSON.stringify(""+b);e.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(e=e.substr(1,e.length-2),e=d(e,"name")):(e=e.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),e=d(e,"string"))}return e+": "+g});k.pop();var n=0;return i=i.reduce(function(a,b){n++;b.indexOf("\n")>=0&&n++;return a+b.length+1},0)>q?b[0]+ -(j===""?"":j+"\n ")+" "+i.join(",\n ")+" "+b[1]:b[0]+j+" "+i.join(", ")+" "+b[1]}var k=[],d=function(a,b){var c={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},d={special:"cyan",number:"blue","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"}[b];return d?"\u001b["+c[d][0]+"m"+a+"\u001b["+c[d][1]+"m":a};f||(d=function(a){return a}); -return m(c,typeof b==="undefined"?2:b)},r=/%[sdj%]/g,s=function(c){if(typeof c!=="string"){for(var h=[],b=0;b=m)return c;switch(c){case "%s":return String(f[b++]);case "%d":return Number(f[b++]);case "%j":return JSON.stringify(f[b++]);case "%%":return"%";default:return c}}),k=f[b];b-1?g.push(f.splice(b,1)):g.push(void 0)):g.push(this.listeners[b]=[]));return g};h.prototype.fire=function(a,c){var b,f,d,e,c=this.makeArray(c); -f=this.listeners[a];if(f!=null){c.push(a);var g;g=[];for(d=0,e=f.length;d - - - jsREPL Sandbox - - - - - diff --git a/vendor/gitbook/jsrepl/sandbox.js b/vendor/gitbook/jsrepl/sandbox.js deleted file mode 100755 index 48f7c74f74..0000000000 --- a/vendor/gitbook/jsrepl/sandbox.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ -(function(c){try{c.window=c.window||c}catch(b){}try{c.self=c.self||c}catch(e){}var a;c.addEventListener("message",function(d){for(var d=JSON.parse(d.data),b=a,c=d.type.split("."),e=0;ethis.OUT_EVERY_MS&&(clearTimeout(this.outTimeout),this.flush())},flush:function(){if(this.output_buffer.length)this.post({type:"output",data:this.output_buffer.join("")}),this.outTimeout=0,this.output_buffer=[]},err:function(a){a={type:"error", -data:a.toString()};this.flush();this.post(a)},input:function(a){this.input.write=a;this.flush();this.post({type:"input"})},result:function(a){a={type:"result",data:a};this.flush();this.post(a)},ready:function(){this.post({type:"ready"})},getNextLineIndent:function(a){this.post({type:"indent",data:this.engine.GetNextLineIndent(a)})},progress:function(a){this.post({type:"progress",data:a})},dbInput:function(){this.flush();this.post({type:"db_input"})},serverInput:function(){this.flush();this.post({type:"server_input"})}, -bindAll:function(a){for(var b in a)(function(b){var c=a[b];typeof c=="function"&&(a[b]=function(){var b=[].slice.call(arguments);return c.apply(a,b)})})(b)},hide:function(a){try{Object.defineProperty(c,a,{writable:false,enumerable:false,configurable:false,value:c[a]})}catch(b){}},set_input_server:function(a){this.input_server={url:(a.url||"/emscripten/input/")+a.input_id,cors:a.cors||false}}};a.bindAll(a);c.Sandboss=a;a.hide("Sandboss");if(self.openDatabaseSync){var f=self.openDatabaseSync("replit_input", -"1.0","Emscripted input",1024);self.prompt=function(){a.dbInput();var b=null;f.transaction(function(a){b=a});for(var c;!(c=b.executeSql("SELECT * FROM input").rows).length;)for(c=0;c<1E8;c++);b.executeSql("DELETE FROM input");return c.item(0).text};a.hide("prompt")}else if(!a.isFrame)self.prompt=function(){a.serverInput();var b;b=a.input_server.url;var c=new XMLHttpRequest;if(a.input_server.cors)if("withCredentials"in c)c.open("GET",b,false);else if(typeof XDomainRequest!="undefined")c=new XDomainRequest, -c.open("GET",b);else throw Error("Your browser doesn' support CORS");else c.open("GET",b,false);b=c;b.send(null);return b.status===200?b.responseText:"ERROR: ON NON-WEBKIT BROWSERS CONNECTION TO THE SERVER IS NEEDED FOR INPUT"}})(this); -(function(){var c=function(b){b==void 0&&(b=Date.now());this.N=624;this.M=397;this.MATRIX_A=2567483615;this.UPPER_MASK=2147483648;this.LOWER_MASK=2147483647;this.mt=Array(this.N);this.mti=this.N+1;this.init_genrand(b)};c.prototype.init_genrand=function(b){this.mt[0]=b>>>0;for(this.mti=1;this.mti>>30,this.mt[this.mti]=(((b&4294901760)>>>16)*1812433253<<16)+(b&65535)*1812433253+this.mti,this.mt[this.mti]>>>=0};c.prototype.init_by_array=function(b, -c){var a,f,d;this.init_genrand(19650218);a=1;f=0;for(d=this.N>c?this.N:c;d;d--){var h=this.mt[a-1]^this.mt[a-1]>>>30;this.mt[a]=(this.mt[a]^(((h&4294901760)>>>16)*1664525<<16)+(h&65535)*1664525)+b[f]+f;this.mt[a]>>>=0;a++;f++;a>=this.N&&(this.mt[0]=this.mt[this.N-1],a=1);f>=c&&(f=0)}for(d=this.N-1;d;d--)h=this.mt[a-1]^this.mt[a-1]>>>30,this.mt[a]=(this.mt[a]^(((h&4294901760)>>>16)*1566083941<<16)+(h&65535)*1566083941)-a,this.mt[a]>>>=0,a++,a>=this.N&&(this.mt[0]=this.mt[this.N-1],a=1);this.mt[0]= -2147483648};c.prototype.genrand_int32=function(){var b,c=[0,this.MATRIX_A];if(this.mti>=this.N){var a;this.mti==this.N+1&&this.init_genrand(5489);for(a=0;a>>1^c[b&1];for(;a>>1^c[b&1];b=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK;this.mt[this.N-1]=this.mt[this.M-1]^ -b>>>1^c[b&1];this.mti=0}b=this.mt[this.mti++];b^=b>>>11;b^=b<<7&2636928640;b^=b<<15&4022730752;b^=b>>>18;return b>>>0};c.prototype.genrand_int31=function(){return this.genrand_int32()>>>1};c.prototype.genrand_real1=function(){return this.genrand_int32()*(1/4294967295)};c.prototype.random=function(){return this.genrand_int32()*(1/4294967296)};c.prototype.genrand_real3=function(){return(this.genrand_int32()+0.5)*(1/4294967296)};c.prototype.genrand_res53=function(){var b=this.genrand_int32()>>>5,c=this.genrand_int32()>>> -6;return(b*67108864+c)*1.1102230246251565E-16};(function(){Math._random=Math.random;var b=new c(42);Math.random=function(){return b.random()};Math.seed=function(e){b=new c(e)}})()})();if(!Date.now)Date.now=function(){return+new Date};if(!Object.keys)Object.keys=function(c){if(c!==Object(c))throw new TypeError("Object.keys called on non-object");var b=[],e;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&b.push(e);return b};if(!Object.getOwnPropertyNames)Object.getOwnPropertyNames=Object.keys; -if(!Object.create)Object.create=function(c){function b(){}b.prototype=c;return new b};if(!Array.isArray)Array.isArray=function(c){return{}.toString.call(c)=="[object Array]"}; -if(!Function.prototype.bind)Function.prototype.bind=function(c){if(typeof this!=="function")throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable");var b=Array.prototype.slice.call(arguments,1),e=this,a=function(){},f=function(){try{return e.apply(this instanceof a?this:c||window,b.concat(Array.prototype.slice.call(arguments)))}catch(d){return e.apply(c||window,b.concat(Array.prototype.slice.call(arguments)))}};a.prototype=this.prototype;f.prototype=new a;return f}; -if(!Object.freeze)Object.freeze=function(c){return c.___frozen___=true};if(!Object.isFrozen)Object.isFrozen=function(c){return Boolean(c.___frozen___)}; diff --git a/vendor/gitbook/plugins/gitbook-plugin-livereload/plugin.js b/vendor/gitbook/plugins/gitbook-plugin-livereload/plugin.js deleted file mode 100644 index 923b3aed5c..0000000000 --- a/vendor/gitbook/plugins/gitbook-plugin-livereload/plugin.js +++ /dev/null @@ -1,11 +0,0 @@ -(function() { - var newEl = document.createElement('script'), - firstScriptTag = document.getElementsByTagName('script')[0]; - - if (firstScriptTag) { - newEl.async = 1; - newEl.src = '//' + window.location.hostname + ':35729/livereload.js'; - firstScriptTag.parentNode.insertBefore(newEl, firstScriptTag); - } - -})(); From b3207545685d7320bd48866df5613d6540c7ef23 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 11:16:46 -0400 Subject: [PATCH 0625/1122] bring back a travis.yml --- .travis.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..8b74cb0f43 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: false +language: rust +cache: cargo +rust: + - stable +branches: + only: + - master +before_script: + - (cargo install mdbook --git https://github.com/azerupi/mdBook.git --force || true) +script: + - mdbook test From 19c720fc354856a4684520848133a4d7f840c618 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 11:29:40 -0400 Subject: [PATCH 0626/1122] chapter 2 --- examples/primitives/array/input.md | 12 ------ examples/primitives/literals/literals.rs | 23 ---------- examples/primitives/primitives.rs | 16 ------- examples/primitives/tuples/input.md | 35 --------------- src/SUMMARY.md | 4 ++ .../primitives/input.md => src/primitives.md | 21 ++++++++- .../array/array.rs => src/primitives/array.md | 15 +++++++ .../input.md => src/primitives/literals.md | 28 +++++++++++- .../tuples.rs => src/primitives/tuples.md | 43 +++++++++++++++++++ 9 files changed, 109 insertions(+), 88 deletions(-) delete mode 100644 examples/primitives/array/input.md delete mode 100644 examples/primitives/literals/literals.rs delete mode 100644 examples/primitives/primitives.rs delete mode 100644 examples/primitives/tuples/input.md rename examples/primitives/input.md => src/primitives.md (60%) rename examples/primitives/array/array.rs => src/primitives/array.md (61%) rename examples/primitives/literals/input.md => src/primitives/literals.md (52%) rename examples/primitives/tuples/tuples.rs => src/primitives/tuples.md (56%) diff --git a/examples/primitives/array/input.md b/examples/primitives/array/input.md deleted file mode 100644 index 8d199b15ba..0000000000 --- a/examples/primitives/array/input.md +++ /dev/null @@ -1,12 +0,0 @@ -An array is a collection of objects of the same type `T`, stored in contiguous -memory. Arrays are created using brackets `[]`, and their size, which is known -at compile time, is part of their type signature `[T; size]`. - -Slices are similar to arrays, but their size is not known at compile time. -Instead, a slice is a two-word object, the first word is a pointer to the data, -and the second word is the length of the slice. The word size is the same as -usize, determined by the processor architecture eg 64 bits on an x86-64. -Slices can be used to borrow a section of an array, and have the type signature -`&[T]`. - -{array.play} diff --git a/examples/primitives/literals/literals.rs b/examples/primitives/literals/literals.rs deleted file mode 100644 index f8d70f7dc7..0000000000 --- a/examples/primitives/literals/literals.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn main() { - // Integer addition - println!("1 + 2 = {}", 1u32 + 2); - - // Integer subtraction - println!("1 - 2 = {}", 1i32 - 2); - // TODO ^ Try changing `1i32` to `1u32` to see why the type is important - - // Short-circuiting boolean logic - println!("true AND false is {}", true && false); - println!("true OR false is {}", true || false); - println!("NOT true is {}", !true); - - // Bitwise operations - println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101); - println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101); - println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101); - println!("1 << 5 is {}", 1u32 << 5); - println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2); - - // Use underscores to improve readability! - println!("One million is written as {}", 1_000_000u32); -} diff --git a/examples/primitives/primitives.rs b/examples/primitives/primitives.rs deleted file mode 100644 index 918b9f7d53..0000000000 --- a/examples/primitives/primitives.rs +++ /dev/null @@ -1,16 +0,0 @@ -fn main() { - // Variables can be type annotated. - let logical: bool = true; - - let a_float: f64 = 1.0; // Regular annotation - let an_integer = 5i32; // Suffix annotation - - // Or a default will be used. - let default_float = 3.0; // `f64` - let default_integer = 7; // `i32` - - let mut mutable = 12; // Mutable `i32`. - - // Error! The type of a variable can't be changed - mutable = true; -} diff --git a/examples/primitives/tuples/input.md b/examples/primitives/tuples/input.md deleted file mode 100644 index a4da7c7857..0000000000 --- a/examples/primitives/tuples/input.md +++ /dev/null @@ -1,35 +0,0 @@ -A tuple is a collection of values of different types. Tuples are constructed -using parentheses `()`, and each tuple itself is a value with type signature -`(T1, T2, ...)`, where `T1`, `T2` are the types of its members. Functions can -use tuples to return multiple values, as tuples can hold any number of values. - -{tuples.play} - -### Activity - - 1. *Recap*: Add the `fmt::Display` trait to the Matrix `struct` in the above example, - so that if you switch from printing the debug format `{:?}` to the display - format `{}`, you see the following output: -``` -( 1.1 1.2 ) -( 2.1 2.2 ) -``` - You may want to refer back to the example for [print display][print_display]. - 2. Add a `transpose` function using the `reverse` function as a template, which - accepts a matrix as an argument, and returns a matrix in which two elements - have been swapped. For example: -``` -println!("Matrix:\n{}", matrix); -println!("Transpose:\n{}", transpose(matrix)); -``` -results in the output: -``` -Matrix: -( 1.1 1.2 ) -( 2.1 2.2 ) -Transpose: -( 1.1 2.1 ) -( 1.2 2.2 ) -``` - -[print_display]: /hello/print/print_display.html diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 21d005750e..3f1bb301f7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -9,3 +9,7 @@ - [Display](hello/print/print_display.md) - [Testcase: List](hello/print/print_display/testcase_list.md) - [Formatting](hello/print/fmt.md) +- [Primitives](primitives.md) + - [Litearls and operators](primitives/literals.md) + - [Tuples](primitives/tuples.md) + - [Arrays and Slices](primitives/array.md) \ No newline at end of file diff --git a/examples/primitives/input.md b/src/primitives.md similarity index 60% rename from examples/primitives/input.md rename to src/primitives.md index 017925fae9..be1721eb95 100644 --- a/examples/primitives/input.md +++ b/src/primitives.md @@ -1,3 +1,5 @@ +# Primitives + Rust provides access to a wide variety of `primitives`. A sample includes: * signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) @@ -13,7 +15,24 @@ Variables can always be *type annotated*. Numbers may additionally be annotated via a *suffix* or *by default*. Integers default to `i32` and floats to `f64`. -{primitives.play} +```rust,editable +fn main() { + // Variables can be type annotated. + let logical: bool = true; + + let a_float: f64 = 1.0; // Regular annotation + let an_integer = 5i32; // Suffix annotation + + // Or a default will be used. + let default_float = 3.0; // `f64` + let default_integer = 7; // `i32` + + let mut mutable = 12; // Mutable `i32`. + + // Error! The type of a variable can't be changed + mutable = true; +} +``` ### See also: diff --git a/examples/primitives/array/array.rs b/src/primitives/array.md similarity index 61% rename from examples/primitives/array/array.rs rename to src/primitives/array.md index 17255f9467..16edd2a0dd 100644 --- a/examples/primitives/array/array.rs +++ b/src/primitives/array.md @@ -1,3 +1,17 @@ +# Arrays and Slices + +An array is a collection of objects of the same type `T`, stored in contiguous +memory. Arrays are created using brackets `[]`, and their size, which is known +at compile time, is part of their type signature `[T; size]`. + +Slices are similar to arrays, but their size is not known at compile time. +Instead, a slice is a two-word object, the first word is a pointer to the data, +and the second word is the length of the slice. The word size is the same as +usize, determined by the processor architecture eg 64 bits on an x86-64. +Slices can be used to borrow a section of an array, and have the type signature +`&[T]`. + +```rust,editable use std::mem; // This function borrows a slice @@ -34,3 +48,4 @@ fn main() { // Out of bound indexing yields a panic println!("{}", xs[5]); } +``` \ No newline at end of file diff --git a/examples/primitives/literals/input.md b/src/primitives/literals.md similarity index 52% rename from examples/primitives/literals/input.md rename to src/primitives/literals.md index 62fbc1f9e1..0a45612e52 100644 --- a/examples/primitives/literals/input.md +++ b/src/primitives/literals.md @@ -1,3 +1,5 @@ +# Litearls and operators + Integers `1`, floats `1.2`, characters `'a'`, strings `"abc"`, booleans `true` and the unit type `()` can be expressed using literals. @@ -14,7 +16,31 @@ integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. The operators available and their precedence [in Rust][rust op-prec] are similar to other [C-like languages][op-prec]. -{literals.play} +```rust,editable +fn main() { + // Integer addition + println!("1 + 2 = {}", 1u32 + 2); + + // Integer subtraction + println!("1 - 2 = {}", 1i32 - 2); + // TODO ^ Try changing `1i32` to `1u32` to see why the type is important + + // Short-circuiting boolean logic + println!("true AND false is {}", true && false); + println!("true OR false is {}", true || false); + println!("NOT true is {}", !true); + + // Bitwise operations + println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101); + println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101); + println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101); + println!("1 << 5 is {}", 1u32 << 5); + println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2); + + // Use underscores to improve readability! + println!("One million is written as {}", 1_000_000u32); +} +``` [rust op-prec]: https://doc.rust-lang.org/reference/expressions.html#operator-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages diff --git a/examples/primitives/tuples/tuples.rs b/src/primitives/tuples.md similarity index 56% rename from examples/primitives/tuples/tuples.rs rename to src/primitives/tuples.md index 2c846470cc..10e089bff6 100644 --- a/examples/primitives/tuples/tuples.rs +++ b/src/primitives/tuples.md @@ -1,3 +1,11 @@ +# Tuples + +A tuple is a collection of values of different types. Tuples are constructed +using parentheses `()`, and each tuple itself is a value with type signature +`(T1, T2, ...)`, where `T1`, `T2` are the types of its members. Functions can +use tuples to return multiple values, as tuples can hold any number of values. + +```rust,editable // Tuples can be used as function arguments and as return values fn reverse(pair: (i32, bool)) -> (bool, i32) { // `let` can be used to bind the members of a tuple to variables @@ -47,3 +55,38 @@ fn main() { println!("{:?}", matrix) } +``` + +### Activity + + 1. *Recap*: Add the `fmt::Display` trait to the Matrix `struct` in the above example, + so that if you switch from printing the debug format `{:?}` to the display + format `{}`, you see the following output: + + ```text + ( 1.1 1.2 ) + ( 2.1 2.2 ) + ``` + + You may want to refer back to the example for [print display][print_display]. + 2. Add a `transpose` function using the `reverse` function as a template, which + accepts a matrix as an argument, and returns a matrix in which two elements + have been swapped. For example: + + ```rust + println!("Matrix:\n{}", matrix); + println!("Transpose:\n{}", transpose(matrix)); + ``` + + results in the output: + + ```text + Matrix: + ( 1.1 1.2 ) + ( 2.1 2.2 ) + Transpose: + ( 1.1 2.1 ) + ( 1.2 2.2 ) + ``` + +[print_display]: /hello/print/print_display.html From 1221131718f74b28c4bc47035f44212eecf33ba3 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 11:45:31 -0400 Subject: [PATCH 0627/1122] chapter 3 --- examples/custom_types/constants/constants.rs | 21 --------------- examples/custom_types/enum/c_like/input.md | 9 ------- examples/custom_types/enum/enum_use/input.md | 10 ------- examples/custom_types/enum/input.md | 15 ----------- .../enum/testcase_linked_list/input.md | 10 ------- examples/custom_types/structs/input.md | 22 ---------------- src/SUMMARY.md | 11 +++++++- .../input.md => src/custom_types.md | 4 ++- .../input.md => src/custom_types/constants.md | 26 ++++++++++++++++++- .../enum/enum.rs => src/custom_types/enum.md | 19 ++++++++++++++ .../custom_types/enum/c_like.md | 12 +++++++++ .../custom_types/enum/enum_use.md | 13 ++++++++++ .../custom_types/enum/testcase_linked_list.md | 13 ++++++++++ .../structs.rs => src/custom_types/structs.md | 25 ++++++++++++++++++ 14 files changed, 120 insertions(+), 90 deletions(-) delete mode 100644 examples/custom_types/constants/constants.rs delete mode 100644 examples/custom_types/enum/c_like/input.md delete mode 100644 examples/custom_types/enum/enum_use/input.md delete mode 100644 examples/custom_types/enum/input.md delete mode 100644 examples/custom_types/enum/testcase_linked_list/input.md delete mode 100644 examples/custom_types/structs/input.md rename examples/custom_types/input.md => src/custom_types.md (90%) rename examples/custom_types/constants/input.md => src/custom_types/constants.md (60%) rename examples/custom_types/enum/enum.rs => src/custom_types/enum.md (77%) rename examples/custom_types/enum/c_like/c_like.rs => src/custom_types/enum/c_like.md (81%) rename examples/custom_types/enum/enum_use/use.rs => src/custom_types/enum/enum_use.md (80%) rename examples/custom_types/enum/testcase_linked_list/linked_list.rs => src/custom_types/enum/testcase_linked_list.md (90%) rename examples/custom_types/structs/structs.rs => src/custom_types/structs.md (61%) diff --git a/examples/custom_types/constants/constants.rs b/examples/custom_types/constants/constants.rs deleted file mode 100644 index 5a22bf967c..0000000000 --- a/examples/custom_types/constants/constants.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Globals are declared outside all other scopes. -static LANGUAGE: &'static str = "Rust"; -const THRESHOLD: i32 = 10; - -fn is_big(n: i32) -> bool { - // Access constant in some function - n > THRESHOLD -} - -fn main() { - let n = 16; - - // Access constant in the main thread - println!("This is {}", LANGUAGE); - println!("The threshold is {}", THRESHOLD); - println!("{} is {}", n, if is_big(n) { "big" } else { "small" }); - - // Error! Cannot modify a `const`. - THRESHOLD = 5; - // FIXME ^ Comment out this line -} diff --git a/examples/custom_types/enum/c_like/input.md b/examples/custom_types/enum/c_like/input.md deleted file mode 100644 index 019e0148d7..0000000000 --- a/examples/custom_types/enum/c_like/input.md +++ /dev/null @@ -1,9 +0,0 @@ -`enum` can also be used as C-like enums. - -{c_like.play} - -### See also: - -[casting][cast] - -[cast]: /cast.html diff --git a/examples/custom_types/enum/enum_use/input.md b/examples/custom_types/enum/enum_use/input.md deleted file mode 100644 index 86b44e6651..0000000000 --- a/examples/custom_types/enum/enum_use/input.md +++ /dev/null @@ -1,10 +0,0 @@ -The `use` declaration can be used so manual scoping isn't needed: - -{use.play} - -### See also: - -[`match`][match] and [`use`][use] - -[use]: /mod/use.html -[match]: /flow_control/match.html diff --git a/examples/custom_types/enum/input.md b/examples/custom_types/enum/input.md deleted file mode 100644 index f32001af09..0000000000 --- a/examples/custom_types/enum/input.md +++ /dev/null @@ -1,15 +0,0 @@ -The `enum` keyword allows the creation of a type which may be one of a few -different variants. Any variant which is valid as a `struct` is also valid as -an `enum`. - -{enum.play} - -### See also: - -[`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] - -[attributes]: /attribute.html -[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[match]: /flow_control/match.html -[fn]: /fn.html -[str]: /std/str.html diff --git a/examples/custom_types/enum/testcase_linked_list/input.md b/examples/custom_types/enum/testcase_linked_list/input.md deleted file mode 100644 index c4ea99ade5..0000000000 --- a/examples/custom_types/enum/testcase_linked_list/input.md +++ /dev/null @@ -1,10 +0,0 @@ -A common use for `enums` is to create a linked-list: - -{linked_list.play} - -### See also: - -[`Box`][box] and [methods][methods] - -[box]: /std/box.html -[methods]: /fn/methods.html diff --git a/examples/custom_types/structs/input.md b/examples/custom_types/structs/input.md deleted file mode 100644 index 73bba902d2..0000000000 --- a/examples/custom_types/structs/input.md +++ /dev/null @@ -1,22 +0,0 @@ -There are three types of structures ("structs") that can be created using the -`struct` keyword: - -* Tuple structs, which are, basically, named tuples. -* The classic [C structs][c_struct] -* Unit structs, which are field-less, are useful for generics. - -{structs.play} - -### Activity - -1. Add a function `rect_area` which calculates the area of a rectangle (try - using nested destructuring). -2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`. - -### See also: - -[`attributes`][attributes] and [destructuring][destructuring] - -[attributes]: /attribute.html -[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[destructuring]: /flow_control/match/destructuring.html diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3f1bb301f7..c33bf27978 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -9,7 +9,16 @@ - [Display](hello/print/print_display.md) - [Testcase: List](hello/print/print_display/testcase_list.md) - [Formatting](hello/print/fmt.md) + - [Primitives](primitives.md) - [Litearls and operators](primitives/literals.md) - [Tuples](primitives/tuples.md) - - [Arrays and Slices](primitives/array.md) \ No newline at end of file + - [Arrays and Slices](primitives/array.md) + +- [Custom Types](custom_types.md) + - [Structures](custom_types/structs.md) + - [Enums](custom_types/enum.md) + - [use](custom_types/enum/enum_use.md) + - [C-like](custom_types/enum/c_like.md) + - [Testcase: linked-list](custom_types/enum/testcase_linked_list.md) + - [constants](custom_types/constants.md) \ No newline at end of file diff --git a/examples/custom_types/input.md b/src/custom_types.md similarity index 90% rename from examples/custom_types/input.md rename to src/custom_types.md index c31c15fd3c..20a408b2e0 100644 --- a/examples/custom_types/input.md +++ b/src/custom_types.md @@ -1,6 +1,8 @@ +# Custom Types + Rust custom data types are formed mainly through the two keywords: * `struct`: define a structure * `enum`: define an enumeration -Constants can also be created via the `const` and `static` keywords. +Constants can also be created via the `const` and `static` keywords. \ No newline at end of file diff --git a/examples/custom_types/constants/input.md b/src/custom_types/constants.md similarity index 60% rename from examples/custom_types/constants/input.md rename to src/custom_types/constants.md index e415e4fa5b..eaaa8340b7 100644 --- a/examples/custom_types/constants/input.md +++ b/src/custom_types/constants.md @@ -1,3 +1,5 @@ +# constants + Rust has two different types of constants which can be declared in any scope including global. Both require explicit type annotation: @@ -11,7 +13,29 @@ types must be specifically annotated so that they fulfill the `'static` lifetime. This may seem minor though because the required explicit annotation hides the distinction. -{constants.play} +```rust,editable +// Globals are declared outside all other scopes. +static LANGUAGE: &'static str = "Rust"; +const THRESHOLD: i32 = 10; + +fn is_big(n: i32) -> bool { + // Access constant in some function + n > THRESHOLD +} + +fn main() { + let n = 16; + + // Access constant in the main thread + println!("This is {}", LANGUAGE); + println!("The threshold is {}", THRESHOLD); + println!("{} is {}", n, if is_big(n) { "big" } else { "small" }); + + // Error! Cannot modify a `const`. + THRESHOLD = 5; + // FIXME ^ Comment out this line +} +``` ### See also: diff --git a/examples/custom_types/enum/enum.rs b/src/custom_types/enum.md similarity index 77% rename from examples/custom_types/enum/enum.rs rename to src/custom_types/enum.md index ee57f2826d..e5a6b5a0da 100644 --- a/examples/custom_types/enum/enum.rs +++ b/src/custom_types/enum.md @@ -1,3 +1,10 @@ +# Enums + +The `enum` keyword allows the creation of a type which may be one of a few +different variants. Any variant which is valid as a `struct` is also valid as +an `enum`. + +```rust,editable // An attribute to hide warnings for unused code. #![allow(dead_code)] @@ -48,3 +55,15 @@ fn main() { inspect(rebecca); inspect(rohan); } + +``` + +### See also: + +[`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] + +[attributes]: /attribute.html +[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) +[match]: /flow_control/match.html +[fn]: /fn.html +[str]: /std/str.html diff --git a/examples/custom_types/enum/c_like/c_like.rs b/src/custom_types/enum/c_like.md similarity index 81% rename from examples/custom_types/enum/c_like/c_like.rs rename to src/custom_types/enum/c_like.md index a0bf6faf15..f5e008aef7 100644 --- a/examples/custom_types/enum/c_like/c_like.rs +++ b/src/custom_types/enum/c_like.md @@ -1,3 +1,8 @@ +# C-like + +`enum` can also be used as C-like enums. + +```rust,editable // An attribute to hide warnings for unused code. #![allow(dead_code)] @@ -23,3 +28,10 @@ fn main() { println!("roses are #{:06x}", Color::Red as i32); println!("violets are #{:06x}", Color::Blue as i32); } +``` + +### See also: + +[casting][cast] + +[cast]: /cast.html diff --git a/examples/custom_types/enum/enum_use/use.rs b/src/custom_types/enum/enum_use.md similarity index 80% rename from examples/custom_types/enum/enum_use/use.rs rename to src/custom_types/enum/enum_use.md index 63a27aa3cb..bddf6ae722 100644 --- a/examples/custom_types/enum/enum_use/use.rs +++ b/src/custom_types/enum/enum_use.md @@ -1,3 +1,8 @@ +# use + +The `use` declaration can be used so manual scoping isn't needed: + +```rust,editable // An attribute to hide warnings for unused code. #![allow(dead_code)] @@ -35,3 +40,11 @@ fn main() { Soldier => println!("Soldiers fight!"), } } +``` + +### See also: + +[`match`][match] and [`use`][use] + +[use]: /mod/use.html +[match]: /flow_control/match.html diff --git a/examples/custom_types/enum/testcase_linked_list/linked_list.rs b/src/custom_types/enum/testcase_linked_list.md similarity index 90% rename from examples/custom_types/enum/testcase_linked_list/linked_list.rs rename to src/custom_types/enum/testcase_linked_list.md index 5a00766051..47fc3269b1 100644 --- a/examples/custom_types/enum/testcase_linked_list/linked_list.rs +++ b/src/custom_types/enum/testcase_linked_list.md @@ -1,3 +1,8 @@ +# Testcase: linked-list + +A common use for `enums` is to create a linked-list: + +```rust,editable use List::*; enum List { @@ -64,3 +69,11 @@ fn main() { println!("linked list has length: {}", list.len()); println!("{}", list.stringify()); } +``` + +### See also: + +[`Box`][box] and [methods][methods] + +[box]: /std/box.html +[methods]: /fn/methods.html diff --git a/examples/custom_types/structs/structs.rs b/src/custom_types/structs.md similarity index 61% rename from examples/custom_types/structs/structs.rs rename to src/custom_types/structs.md index 3332f88eab..3c99f6dcde 100644 --- a/examples/custom_types/structs/structs.rs +++ b/src/custom_types/structs.md @@ -1,3 +1,13 @@ +# Structures + +There are three types of structures ("structs") that can be created using the +`struct` keyword: + +* Tuple structs, which are, basically, named tuples. +* The classic [C structs][c_struct] +* Unit structs, which are field-less, are useful for generics. + +```rust,editable #[derive(Debug)] struct Person<'a> { name: &'a str, @@ -62,3 +72,18 @@ fn main() { println!("pair contains {:?} and {:?}", integer, decimal); } +``` + +### Activity + +1. Add a function `rect_area` which calculates the area of a rectangle (try + using nested destructuring). +2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`. + +### See also: + +[`attributes`][attributes] and [destructuring][destructuring] + +[attributes]: /attribute.html +[c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) +[destructuring]: /flow_control/match/destructuring.html From f786cf3ded353f4b8683c4e0480c1fb83b567225 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 11:56:35 -0400 Subject: [PATCH 0628/1122] Chapter 4 --- examples/variable_bindings/declare/input.md | 8 -------- examples/variable_bindings/input.md | 8 -------- examples/variable_bindings/mut/input.md | 6 ------ examples/variable_bindings/scope/input.md | 7 ------- src/SUMMARY.md | 7 ++++++- .../variable_bindings.rs => src/variable_bindings.md | 11 +++++++++++ .../declare.rs => src/variable_bindings/declare.md | 11 +++++++++++ .../mut/mut.rs => src/variable_bindings/mut.md | 9 +++++++++ .../scope/scope.rs => src/variable_bindings/scope.md | 10 ++++++++++ 9 files changed, 47 insertions(+), 30 deletions(-) delete mode 100644 examples/variable_bindings/declare/input.md delete mode 100644 examples/variable_bindings/input.md delete mode 100644 examples/variable_bindings/mut/input.md delete mode 100644 examples/variable_bindings/scope/input.md rename examples/variable_bindings/variable_bindings.rs => src/variable_bindings.md (62%) rename examples/variable_bindings/declare/declare.rs => src/variable_bindings/declare.md (59%) rename examples/variable_bindings/mut/mut.rs => src/variable_bindings/mut.md (59%) rename examples/variable_bindings/scope/scope.rs => src/variable_bindings/scope.md (73%) diff --git a/examples/variable_bindings/declare/input.md b/examples/variable_bindings/declare/input.md deleted file mode 100644 index 63339745ae..0000000000 --- a/examples/variable_bindings/declare/input.md +++ /dev/null @@ -1,8 +0,0 @@ -It's possible to declare variable bindings first, and initialize them later. -However, this form is seldom used, as it may lead to the use of uninitialized -variables. - -{declare.play} - -The compiler forbids use of uninitialized variables, as this would lead to -undefined behavior. diff --git a/examples/variable_bindings/input.md b/examples/variable_bindings/input.md deleted file mode 100644 index 160d49ba48..0000000000 --- a/examples/variable_bindings/input.md +++ /dev/null @@ -1,8 +0,0 @@ -Rust provides type safety via static typing. Variable bindings can be type -annotated when declared. However, in most cases, the compiler will be able -to infer the type of the variable from the context, heavily reducing the -annotation burden. - -Values (like literals) can be bound to variables, using the `let` binding. - -{variable_bindings.play} diff --git a/examples/variable_bindings/mut/input.md b/examples/variable_bindings/mut/input.md deleted file mode 100644 index ca010fee4d..0000000000 --- a/examples/variable_bindings/mut/input.md +++ /dev/null @@ -1,6 +0,0 @@ -Variable bindings are immutable by default, but this can be overridden using -the `mut` modifier. - -{mut.play} - -The compiler will throw a detailed diagnostic about mutability errors. diff --git a/examples/variable_bindings/scope/input.md b/examples/variable_bindings/scope/input.md deleted file mode 100644 index ff558df92a..0000000000 --- a/examples/variable_bindings/scope/input.md +++ /dev/null @@ -1,7 +0,0 @@ -Variable bindings have a scope, and are constrained to live in a *block*. A -block is a collection of statements enclosed by braces `{}`. Also, [variable -shadowing][variable-shadow] is allowed. - -{scope.play} - -[variable-shadow]: https://en.wikipedia.org/wiki/Variable_shadowing diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c33bf27978..f801999a5c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -21,4 +21,9 @@ - [use](custom_types/enum/enum_use.md) - [C-like](custom_types/enum/c_like.md) - [Testcase: linked-list](custom_types/enum/testcase_linked_list.md) - - [constants](custom_types/constants.md) \ No newline at end of file + - [constants](custom_types/constants.md) + +- [Variable Bindings](variable_bindings.md) + - [Mutability](variable_bindings/mut.md) + - [Scope and Shadowing](variable_bindings/scope.md) + - [Declare first](variable_bindings/declare.md) \ No newline at end of file diff --git a/examples/variable_bindings/variable_bindings.rs b/src/variable_bindings.md similarity index 62% rename from examples/variable_bindings/variable_bindings.rs rename to src/variable_bindings.md index 25bd9a2658..b280ed5486 100644 --- a/examples/variable_bindings/variable_bindings.rs +++ b/src/variable_bindings.md @@ -1,3 +1,13 @@ +# Variable Bindings + +Rust provides type safety via static typing. Variable bindings can be type +annotated when declared. However, in most cases, the compiler will be able +to infer the type of the variable from the context, heavily reducing the +annotation burden. + +Values (like literals) can be bound to variables, using the `let` binding. + +```rust,editable fn main() { let an_integer = 1u32; let a_boolean = true; @@ -17,3 +27,4 @@ fn main() { let noisy_unused_variable = 2u32; // FIXME ^ Prefix with an underscore to suppress the warning } +``` \ No newline at end of file diff --git a/examples/variable_bindings/declare/declare.rs b/src/variable_bindings/declare.md similarity index 59% rename from examples/variable_bindings/declare/declare.rs rename to src/variable_bindings/declare.md index a678cfbb65..574eb6f71c 100644 --- a/examples/variable_bindings/declare/declare.rs +++ b/src/variable_bindings/declare.md @@ -1,3 +1,10 @@ +# Declare first + +It's possible to declare variable bindings first, and initialize them later. +However, this form is seldom used, as it may lead to the use of uninitialized +variables. + +```rust,editable fn main() { // Declare a variable binding let a_binding; @@ -21,3 +28,7 @@ fn main() { println!("another binding: {}", another_binding); } +``` + +The compiler forbids use of uninitialized variables, as this would lead to +undefined behavior. diff --git a/examples/variable_bindings/mut/mut.rs b/src/variable_bindings/mut.md similarity index 59% rename from examples/variable_bindings/mut/mut.rs rename to src/variable_bindings/mut.md index 72695e12ff..5a1f1eb9ab 100644 --- a/examples/variable_bindings/mut/mut.rs +++ b/src/variable_bindings/mut.md @@ -1,3 +1,9 @@ +# Mutability + +Variable bindings are immutable by default, but this can be overridden using +the `mut` modifier. + +```rust,editable fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; @@ -13,3 +19,6 @@ fn main() { _immutable_binding += 1; // FIXME ^ Comment out this line } +``` + +The compiler will throw a detailed diagnostic about mutability errors. diff --git a/examples/variable_bindings/scope/scope.rs b/src/variable_bindings/scope.md similarity index 73% rename from examples/variable_bindings/scope/scope.rs rename to src/variable_bindings/scope.md index 4d923989e7..a29268b801 100644 --- a/examples/variable_bindings/scope/scope.rs +++ b/src/variable_bindings/scope.md @@ -1,3 +1,10 @@ +# Scope and Shadowing + +Variable bindings have a scope, and are constrained to live in a *block*. A +block is a collection of statements enclosed by braces `{}`. Also, [variable +shadowing][variable-shadow] is allowed. + +```rust,editable fn main() { // This binding lives in the main function let long_lived_binding = 1; @@ -27,3 +34,6 @@ fn main() { println!("outer long: {}", long_lived_binding); } +``` + +[variable-shadow]: https://en.wikipedia.org/wiki/Variable_shadowing From b7414e112b7c963f1b300bb34fee5e6b5bfbfc13 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:13:58 -0400 Subject: [PATCH 0629/1122] Chapter 5 --- examples/cast/alias/input.md | 12 ---------- examples/cast/inference/input.md | 12 ---------- examples/cast/input.md | 8 ------- examples/cast/literals/literals.rs | 17 -------------- src/SUMMARY.md | 7 +++++- examples/cast/cast.rs => src/cast.md | 13 +++++++++-- .../cast/alias/alias.rs => src/cast/alias.md | 15 +++++++++++++ .../inference.rs => src/cast/inference.md | 15 +++++++++++++ .../literals/input.md => src/cast/literals.md | 22 ++++++++++++++++++- 9 files changed, 68 insertions(+), 53 deletions(-) delete mode 100644 examples/cast/alias/input.md delete mode 100644 examples/cast/inference/input.md delete mode 100644 examples/cast/input.md delete mode 100644 examples/cast/literals/literals.rs rename examples/cast/cast.rs => src/cast.md (81%) rename examples/cast/alias/alias.rs => src/cast/alias.md (58%) rename examples/cast/inference/inference.rs => src/cast/inference.md (54%) rename examples/cast/literals/input.md => src/cast/literals.md (60%) diff --git a/examples/cast/alias/input.md b/examples/cast/alias/input.md deleted file mode 100644 index 9868a5f5c7..0000000000 --- a/examples/cast/alias/input.md +++ /dev/null @@ -1,12 +0,0 @@ -The `type` statement can be used to give a new name to an existing type. Types -must have `CamelCase` names, or the compiler will raise a warning. The -exception to this rule are the primitive types: `usize`, `f32`, etc. - -{alias.play} - -The main use of aliases is to reduce boilerplate; for example the `IoResult` type -is an alias for the `Result` type. - -### See also: - -[Attributes](/attribute.html) diff --git a/examples/cast/inference/input.md b/examples/cast/inference/input.md deleted file mode 100644 index cf592cddad..0000000000 --- a/examples/cast/inference/input.md +++ /dev/null @@ -1,12 +0,0 @@ -The type inference engine is pretty smart. It does more than looking at the -type of the -[r-value][rvalue] -during an initialization. It also looks at how the variable is used afterwards -to infer its type. Here's an advanced example of type inference: - -{inference.play} - -No type annotation of variables was needed, the compiler is happy and so is the -programmer! - -[rvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue diff --git a/examples/cast/input.md b/examples/cast/input.md deleted file mode 100644 index 658dd9cce9..0000000000 --- a/examples/cast/input.md +++ /dev/null @@ -1,8 +0,0 @@ -Rust provides no implicit type conversion (coercion) between primitive types. -But, explicit type conversion (casting) can be performed using the `as` keyword. - -Rules for converting between integral types follow C conventions generally, -except in cases where C has undefined behavior. The behavior of all casts -between integral types is well defined in Rust. - -{cast.play} diff --git a/examples/cast/literals/literals.rs b/examples/cast/literals/literals.rs deleted file mode 100644 index c0fe85f2be..0000000000 --- a/examples/cast/literals/literals.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn main() { - // Suffixed literals, their types are known at initialization - let x = 1u8; - let y = 2u32; - let z = 3f32; - - // Unsuffixed literal, their types depend on how they are used - let i = 1; - let f = 1.0; - - // `size_of_val` returns the size of a variable in bytes - println!("size of `x` in bytes: {}", std::mem::size_of_val(&x)); - println!("size of `y` in bytes: {}", std::mem::size_of_val(&y)); - println!("size of `z` in bytes: {}", std::mem::size_of_val(&z)); - println!("size of `i` in bytes: {}", std::mem::size_of_val(&i)); - println!("size of `f` in bytes: {}", std::mem::size_of_val(&f)); -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index f801999a5c..a0a9dab44c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -26,4 +26,9 @@ - [Variable Bindings](variable_bindings.md) - [Mutability](variable_bindings/mut.md) - [Scope and Shadowing](variable_bindings/scope.md) - - [Declare first](variable_bindings/declare.md) \ No newline at end of file + - [Declare first](variable_bindings/declare.md) + +- [Casting](cast.md) + - [Literals](cast/literals.md) + - [Inference](cast/inference.md) + - [Aliasing](cast/alias.md) \ No newline at end of file diff --git a/examples/cast/cast.rs b/src/cast.md similarity index 81% rename from examples/cast/cast.rs rename to src/cast.md index b91f8025df..5b0a3f5525 100644 --- a/examples/cast/cast.rs +++ b/src/cast.md @@ -1,3 +1,13 @@ +# Casting + +Rust provides no implicit type conversion (coercion) between primitive types. +But, explicit type conversion (casting) can be performed using the `as` keyword. + +Rules for converting between integral types follow C conventions generally, +except in cases where C has undefined behavior. The behavior of all casts +between integral types is well defined in Rust. + +```rust,editable // Suppress all warnings from casts which overflow. #![allow(overflowing_literals)] @@ -45,6 +55,5 @@ fn main() { println!("1000 as a i8 is : {}", 1000 as i8); // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); - - } +``` \ No newline at end of file diff --git a/examples/cast/alias/alias.rs b/src/cast/alias.md similarity index 58% rename from examples/cast/alias/alias.rs rename to src/cast/alias.md index 74e6f52938..cad75c7bea 100644 --- a/examples/cast/alias/alias.rs +++ b/src/cast/alias.md @@ -1,3 +1,10 @@ +# Aliasing + +The `type` statement can be used to give a new name to an existing type. Types +must have `CamelCase` names, or the compiler will raise a warning. The +exception to this rule are the primitive types: `usize`, `f32`, etc. + +```rust,editable // `NanoSecond` is a new name for `u64`. type NanoSecond = u64; type Inch = u64; @@ -19,3 +26,11 @@ fn main() { inches, nanoseconds + inches); } +``` + +The main use of aliases is to reduce boilerplate; for example the `IoResult` type +is an alias for the `Result` type. + +### See also: + +[Attributes](/attribute.html) \ No newline at end of file diff --git a/examples/cast/inference/inference.rs b/src/cast/inference.md similarity index 54% rename from examples/cast/inference/inference.rs rename to src/cast/inference.md index 8dde5abe56..be081d5f30 100644 --- a/examples/cast/inference/inference.rs +++ b/src/cast/inference.md @@ -1,3 +1,12 @@ +# Inference + +The type inference engine is pretty smart. It does more than looking at the +type of the +[r-value][rvalue] +during an initialization. It also looks at how the variable is used afterwards +to infer its type. Here's an advanced example of type inference: + +```rust,editable fn main() { // Because of the annotation, the compiler knows that `elem` has type u8. let elem = 5u8; @@ -14,3 +23,9 @@ fn main() { println!("{:?}", vec); } +``` + +No type annotation of variables was needed, the compiler is happy and so is the +programmer! + +[rvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue diff --git a/examples/cast/literals/input.md b/src/cast/literals.md similarity index 60% rename from examples/cast/literals/input.md rename to src/cast/literals.md index 08956a43c6..cf33b6a0cb 100644 --- a/examples/cast/literals/input.md +++ b/src/cast/literals.md @@ -1,3 +1,5 @@ +# Literals + Numeric literals can be type annotated by adding the type as a suffix. As an example, to specify that the literal `42` should have the type `i32`, write `42i32`. @@ -5,7 +7,25 @@ The type of unsuffixed numeric literals will depend on how they are used. If no constraint exists, the compiler will use `i32` for integers, and `f64` for floating-point numbers. -{literals.play} +```rust,editable +fn main() { + // Suffixed literals, their types are known at initialization + let x = 1u8; + let y = 2u32; + let z = 3f32; + + // Unsuffixed literal, their types depend on how they are used + let i = 1; + let f = 1.0; + + // `size_of_val` returns the size of a variable in bytes + println!("size of `x` in bytes: {}", std::mem::size_of_val(&x)); + println!("size of `y` in bytes: {}", std::mem::size_of_val(&y)); + println!("size of `z` in bytes: {}", std::mem::size_of_val(&z)); + println!("size of `i` in bytes: {}", std::mem::size_of_val(&i)); + println!("size of `f` in bytes: {}", std::mem::size_of_val(&f)); +} +``` There are some concepts used in the previous code that haven't been explained yet, here's a brief explanation for the impatient readers: From 8de0d3ee8eaef04409679554e78a996232a79a0c Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:30:30 -0400 Subject: [PATCH 0630/1122] Chapter 6 --- examples/expression/expression.rs | 20 -------------- src/SUMMARY.md | 4 ++- .../expression/input.md => src/expression.md | 26 +++++++++++++++++-- 3 files changed, 27 insertions(+), 23 deletions(-) delete mode 100644 examples/expression/expression.rs rename examples/expression/input.md => src/expression.md (64%) diff --git a/examples/expression/expression.rs b/examples/expression/expression.rs deleted file mode 100644 index 09a7ff06d5..0000000000 --- a/examples/expression/expression.rs +++ /dev/null @@ -1,20 +0,0 @@ -fn main() { - let x = 5u32; - - let y = { - let x_squared = x * x; - let x_cube = x_squared * x; - - // This expression will be assigned to `y` - x_cube + x_squared + x - }; - - let z = { - // The semicolon suppresses this expression and `()` is assigned to `z` - 2 * x; - }; - - println!("x is {:?}", x); - println!("y is {:?}", y); - println!("z is {:?}", z); -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a0a9dab44c..8f972971e7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -31,4 +31,6 @@ - [Casting](cast.md) - [Literals](cast/literals.md) - [Inference](cast/inference.md) - - [Aliasing](cast/alias.md) \ No newline at end of file + - [Aliasing](cast/alias.md) + +- [Expressions](expression.md) \ No newline at end of file diff --git a/examples/expression/input.md b/src/expression.md similarity index 64% rename from examples/expression/input.md rename to src/expression.md index 174cba2ffd..e13a075c9f 100644 --- a/examples/expression/input.md +++ b/src/expression.md @@ -1,5 +1,6 @@ -A Rust program is (mostly) made up of a series of statements: +# Expressions +A Rust program is (mostly) made up of a series of statements: ``` fn main() { @@ -29,7 +30,28 @@ assignments. The last expression in the block will be assigned to the [l-value][lvalue]. However, if the last expression of the block ends with a semicolon, the return value will be `()`. -{expression.play} +```rust,editable +fn main() { + let x = 5u32; + + let y = { + let x_squared = x * x; + let x_cube = x_squared * x; + + // This expression will be assigned to `y` + x_cube + x_squared + x + }; + + let z = { + // The semicolon suppresses this expression and `()` is assigned to `z` + 2 * x; + }; + + println!("x is {:?}", x); + println!("y is {:?}", y); + println!("z is {:?}", z); +} +``` [rvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue [lvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue From c3d9a108ccd866f378ded801c4572c6ee33c4c35 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:33:17 -0400 Subject: [PATCH 0631/1122] fill out chapters in SUMMARY.md --- src/SUMMARY.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8f972971e7..e18ca0066d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -33,4 +33,32 @@ - [Inference](cast/inference.md) - [Aliasing](cast/alias.md) -- [Expressions](expression.md) \ No newline at end of file +- [Expressions](expression.md) + +- [Flow control]() + +- [Functions]() + +- [Modules]() + +- [Crates]() + +- [Attributes]() + +- [Generics]() + +- [Scoping Rules]() + +- [Traits]() + +- [macro_rules!]() + +- [Error Handling]() + +- [Std library types]() + +- [Std misc]() + +- [Meta]() + +- [Unsafe Operations]() \ No newline at end of file From 51d31c1a2a5b156d2c8d141fdbb6d8a625eae915 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:36:13 -0400 Subject: [PATCH 0632/1122] chapter 10 --- examples/crates/lib/input.md | 15 --------- examples/crates/lib/rary.rs | 13 -------- examples/crates/link/executable.rs | 11 ------- src/SUMMARY.md | 4 ++- examples/crates/input.md => src/crates.md | 4 ++- src/crates/lib.md | 31 +++++++++++++++++++ .../link/input.md => src/crates/link.md | 16 +++++++++- 7 files changed, 52 insertions(+), 42 deletions(-) delete mode 100644 examples/crates/lib/input.md delete mode 100644 examples/crates/lib/rary.rs delete mode 100644 examples/crates/link/executable.rs rename examples/crates/input.md => src/crates.md (92%) create mode 100644 src/crates/lib.md rename examples/crates/link/input.md => src/crates/link.md (67%) diff --git a/examples/crates/lib/input.md b/examples/crates/lib/input.md deleted file mode 100644 index 228c566e61..0000000000 --- a/examples/crates/lib/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Let's create a library, and then see how to link it to another crate. - -{rary.rs} - -``` -$ rustc --crate-type=lib rary.rs -$ ls lib* -library.rlib -``` - -Libraries get prefixed with "lib", and by default they get named after their -crate file, but this default name can be overridden using the [`crate_name` -attribute][crate-name]. - -[crate-name]: /attribute/crate.html diff --git a/examples/crates/lib/rary.rs b/examples/crates/lib/rary.rs deleted file mode 100644 index d9425982a1..0000000000 --- a/examples/crates/lib/rary.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub fn public_function() { - println!("called rary's `public_function()`"); -} - -fn private_function() { - println!("called rary's `private_function()`"); -} - -pub fn indirect_access() { - print!("called rary's `indirect_access()`, that\n> "); - - private_function(); -} diff --git a/examples/crates/link/executable.rs b/examples/crates/link/executable.rs deleted file mode 100644 index 6942105ee4..0000000000 --- a/examples/crates/link/executable.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Link to `library`, import items under the `rary` module -extern crate rary; - -fn main() { - rary::public_function(); - - // Error! `private_function` is private - //rary::private_function(); - - rary::indirect_access(); -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e18ca0066d..5a9811e5b0 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -41,7 +41,9 @@ - [Modules]() -- [Crates]() +- [Crates](crates.md) + - [Library](crates/lib.md) + - [`extern crate`](crates/link.md) - [Attributes]() diff --git a/examples/crates/input.md b/src/crates.md similarity index 92% rename from examples/crates/input.md rename to src/crates.md index 1fa3ad9809..44f714bee3 100644 --- a/examples/crates/input.md +++ b/src/crates.md @@ -1,3 +1,5 @@ +# Crates + A crate is a compilation unit in Rust. Whenever `rustc some_file.rs` is called, `some_file.rs` is treated as the *crate file*. If `some_file.rs` has `mod` declarations in it, then the contents of the module files will get merged with @@ -6,4 +8,4 @@ do *not* get compiled individually, only crates get compiled. A crate can be compiled into a binary or into a library. By default, `rustc` will produce a binary from a crate. This behavior can be overridden by passing -the `--crate-type` flag to `rustc`. +the `--crate-type` flag to `rustc`. \ No newline at end of file diff --git a/src/crates/lib.md b/src/crates/lib.md new file mode 100644 index 0000000000..16e7128dbc --- /dev/null +++ b/src/crates/lib.md @@ -0,0 +1,31 @@ +# Library + +Let's create a library, and then see how to link it to another crate. + +```rust,editable +pub fn public_function() { + println!("called rary's `public_function()`"); +} + +fn private_function() { + println!("called rary's `private_function()`"); +} + +pub fn indirect_access() { + print!("called rary's `indirect_access()`, that\n> "); + + private_function(); +} +``` + +```bash +$ rustc --crate-type=lib rary.rs +$ ls lib* +library.rlib +``` + +Libraries get prefixed with "lib", and by default they get named after their +crate file, but this default name can be overridden using the [`crate_name` +attribute][crate-name]. + +[crate-name]: /attribute/crate.html \ No newline at end of file diff --git a/examples/crates/link/input.md b/src/crates/link.md similarity index 67% rename from examples/crates/link/input.md rename to src/crates/link.md index c6ef3d382b..c7eabdbfbd 100644 --- a/examples/crates/link/input.md +++ b/src/crates/link.md @@ -1,11 +1,25 @@ +# `extern crate` + To link a crate to this new library, the `extern crate` declaration must be used. This will not only link the library, but also import all its items under a module named the same as the library. The visibility rules that apply to modules also apply to libraries. -{executable.rs} +```rust,editable +// Link to `library`, import items under the `rary` module +extern crate rary; + +fn main() { + rary::public_function(); + // Error! `private_function` is private + //rary::private_function(); + + rary::indirect_access(); +} ``` + +```bash # Where library.rlib is the path to to the compiled library, assumed that it's # in the same directory here: $ rustc executable.rs --extern rary=library.rlib && ./executable From 38d715fe867e37a13bde31727fccf81376ff787a Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:43:32 -0400 Subject: [PATCH 0633/1122] Chapter 11 --- examples/attribute/cfg/custom/custom.rs | 8 ----- examples/attribute/cfg/input.md | 16 --------- examples/attribute/crate/input.md | 14 -------- examples/attribute/crate/lib.rs | 18 ---------- examples/attribute/unused/unused.rs | 12 ------- src/SUMMARY.md | 6 +++- .../attribute/input.md => src/attribute.md | 2 ++ .../cfg/cfg.rs => src/attribute/cfg.md | 19 ++++++++++ .../input.md => src/attribute/cfg/custom.md | 17 ++++++--- src/attribute/crate.md | 35 +++++++++++++++++++ .../input.md => src/attribute/unused.md | 17 ++++++++- 11 files changed, 90 insertions(+), 74 deletions(-) delete mode 100644 examples/attribute/cfg/custom/custom.rs delete mode 100644 examples/attribute/cfg/input.md delete mode 100644 examples/attribute/crate/input.md delete mode 100644 examples/attribute/crate/lib.rs delete mode 100644 examples/attribute/unused/unused.rs rename examples/attribute/input.md => src/attribute.md (98%) rename examples/attribute/cfg/cfg.rs => src/attribute/cfg.md (53%) rename examples/attribute/cfg/custom/input.md => src/attribute/cfg/custom.md (52%) create mode 100644 src/attribute/crate.md rename examples/attribute/unused/input.md => src/attribute/unused.md (55%) diff --git a/examples/attribute/cfg/custom/custom.rs b/examples/attribute/cfg/custom/custom.rs deleted file mode 100644 index 19ad641852..0000000000 --- a/examples/attribute/cfg/custom/custom.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(some_condition)] -fn conditional_function() { - println!("condition met!") -} - -fn main() { - conditional_function(); -} diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md deleted file mode 100644 index 7b4a21a37c..0000000000 --- a/examples/attribute/cfg/input.md +++ /dev/null @@ -1,16 +0,0 @@ -Conditional compilation is possible through two different operators: - -* the `cfg` attribute: `#[cfg(...)]` in attribute position -* the `cfg!` macro: `cfg!(...)` in boolean expressions - -Both utilize identical argument syntax. - -{cfg.play} - -### See also: - -[the reference][ref], [`cfg!`][cfg], and [macros][macros]. - -[cfg]: https://doc.rust-lang.org/std/macro.cfg!.html -[macros]: /macros.html -[ref]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation diff --git a/examples/attribute/crate/input.md b/examples/attribute/crate/input.md deleted file mode 100644 index 8bf8e4b286..0000000000 --- a/examples/attribute/crate/input.md +++ /dev/null @@ -1,14 +0,0 @@ -The `crate_type` attribute can be used to tell the compiler whether a crate is -a binary or a library (and even which type of library), and the `crate_name` -attribute can be used to set the name of the crate. - -{lib.rs} - -When the `crate_type` attribute is used, we no longer need to pass the -`--crate-type` flag to `rustc`. - -``` -$ rustc lib.rs -$ ls lib* -library.rlib -``` diff --git a/examples/attribute/crate/lib.rs b/examples/attribute/crate/lib.rs deleted file mode 100644 index 39afc16f51..0000000000 --- a/examples/attribute/crate/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -// This crate is a library -#![crate_type = "lib"] -// The library is named "rary" -#![crate_name = "rary"] - -pub fn public_function() { - println!("called rary's `public_function()`"); -} - -fn private_function() { - println!("called rary's `private_function()`"); -} - -pub fn indirect_access() { - print!("called rary's `indirect_access()`, that\n> "); - - private_function(); -} diff --git a/examples/attribute/unused/unused.rs b/examples/attribute/unused/unused.rs deleted file mode 100644 index bae5665576..0000000000 --- a/examples/attribute/unused/unused.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn used_function() {} - -// `#[allow(dead_code)]` is an attribute that disables the `dead_code` lint -#[allow(dead_code)] -fn unused_function() {} - -fn noisy_unused_function() {} -// FIXME ^ Add an attribute to suppress the warning - -fn main() { - used_function(); -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5a9811e5b0..80d1f7cde8 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -45,7 +45,11 @@ - [Library](crates/lib.md) - [`extern crate`](crates/link.md) -- [Attributes]() +- [Attributes](attribute.md) + - [`dead_code`](attribute/unused.md) + - [Crates](attribute/crate.md) + - [`cfg`](attribute/cfg.md) + - [Custom](attribute/cfg/custom.md) - [Generics]() diff --git a/examples/attribute/input.md b/src/attribute.md similarity index 98% rename from examples/attribute/input.md rename to src/attribute.md index 13c3a051a2..574d893221 100644 --- a/examples/attribute/input.md +++ b/src/attribute.md @@ -1,3 +1,5 @@ +# Attributes + An attribute is metadata applied to some module, crate or item. This metadata can be used to/for: diff --git a/examples/attribute/cfg/cfg.rs b/src/attribute/cfg.md similarity index 53% rename from examples/attribute/cfg/cfg.rs rename to src/attribute/cfg.md index 60020174e5..c2e95728b6 100644 --- a/examples/attribute/cfg/cfg.rs +++ b/src/attribute/cfg.md @@ -1,3 +1,13 @@ +# `cfg` + +Conditional compilation is possible through two different operators: + +* the `cfg` attribute: `#[cfg(...)]` in attribute position +* the `cfg!` macro: `cfg!(...)` in boolean expressions + +Both utilize identical argument syntax. + +```rust,editable // This function only gets compiled if the target OS is linux #[cfg(target_os = "linux")] fn are_you_on_linux() { @@ -20,3 +30,12 @@ fn main() { println!("Yes. It's definitely *not* linux!"); } } +``` + +### See also: + +[the reference][ref], [`cfg!`][cfg], and [macros][macros]. + +[cfg]: https://doc.rust-lang.org/std/macro.cfg!.html +[macros]: /macros.html +[ref]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation diff --git a/examples/attribute/cfg/custom/input.md b/src/attribute/cfg/custom.md similarity index 52% rename from examples/attribute/cfg/custom/input.md rename to src/attribute/cfg/custom.md index 75b04dd853..2e2bc419a5 100644 --- a/examples/attribute/cfg/custom/input.md +++ b/src/attribute/cfg/custom.md @@ -1,15 +1,24 @@ +# Custom + Some conditionals like `target_os` are implicitly provided by `rustc`, but custom conditionals must be passed to `rustc` using the `--cfg` flag. -{custom.rs} +```rust,editable +#[cfg(some_condition)] +fn conditional_function() { + println!("condition met!") +} -Without the custom `cfg` flag: +fn main() { + conditional_function(); +} +``` -{custom.out} +Try to run this to see what happens without the custom `cfg` flag. With the custom `cfg` flag: -``` +```bash $ rustc --cfg some_condition custom.rs && ./custom condition met! ``` diff --git a/src/attribute/crate.md b/src/attribute/crate.md new file mode 100644 index 0000000000..5268aa7242 --- /dev/null +++ b/src/attribute/crate.md @@ -0,0 +1,35 @@ +# Crates + +The `crate_type` attribute can be used to tell the compiler whether a crate is +a binary or a library (and even which type of library), and the `crate_name` +attribute can be used to set the name of the crate. + +```rust,editable +// This crate is a library +#![crate_type = "lib"] +// The library is named "rary" +#![crate_name = "rary"] + +pub fn public_function() { + println!("called rary's `public_function()`"); +} + +fn private_function() { + println!("called rary's `private_function()`"); +} + +pub fn indirect_access() { + print!("called rary's `indirect_access()`, that\n> "); + + private_function(); +} +``` + +When the `crate_type` attribute is used, we no longer need to pass the +`--crate-type` flag to `rustc`. + +```bash +$ rustc lib.rs +$ ls lib* +library.rlib +``` diff --git a/examples/attribute/unused/input.md b/src/attribute/unused.md similarity index 55% rename from examples/attribute/unused/input.md rename to src/attribute/unused.md index 9295a087f1..1eab374808 100644 --- a/examples/attribute/unused/input.md +++ b/src/attribute/unused.md @@ -1,8 +1,23 @@ +# `dead_code` + The compiler provides a `dead_code` [*lint*][lint] that will warn about unused functions. An *attribute* can be used to disable the lint. -{unused.play} +```rust,editable +fn used_function() {} + +// `#[allow(dead_code)]` is an attribute that disables the `dead_code` lint +#[allow(dead_code)] +fn unused_function() {} + +fn noisy_unused_function() {} +// FIXME ^ Add an attribute to suppress the warning + +fn main() { + used_function(); +} +``` Note that in real programs, you should eliminate dead code. In these examples we'll allow dead code in some places because of the interactive nature of the From b739bd2b0590be2b7fd68578b2b2be3c0adfb41c Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:46:27 -0400 Subject: [PATCH 0634/1122] Chapter 20 --- examples/unsafe/pointer.rs | 7 ------- examples/unsafe/transmute.rs | 7 ------- src/SUMMARY.md | 2 +- examples/unsafe/input.md => src/unsafe.md | 22 ++++++++++++++++++++-- 4 files changed, 21 insertions(+), 17 deletions(-) delete mode 100644 examples/unsafe/pointer.rs delete mode 100644 examples/unsafe/transmute.rs rename examples/unsafe/input.md => src/unsafe.md (76%) diff --git a/examples/unsafe/pointer.rs b/examples/unsafe/pointer.rs deleted file mode 100644 index ba494622cc..0000000000 --- a/examples/unsafe/pointer.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let raw_p: *const u32 = &10; - - unsafe { - assert!(*raw_p == 10); - } -} diff --git a/examples/unsafe/transmute.rs b/examples/unsafe/transmute.rs deleted file mode 100644 index 27ba8a5b31..0000000000 --- a/examples/unsafe/transmute.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let u: &[u8] = &[49, 50, 51]; - - unsafe { - assert!(u == std::mem::transmute::<&str, &[u8]>("123")); - } -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 80d1f7cde8..39341a594a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -67,4 +67,4 @@ - [Meta]() -- [Unsafe Operations]() \ No newline at end of file +- [Unsafe Operations](unsafe.md) \ No newline at end of file diff --git a/examples/unsafe/input.md b/src/unsafe.md similarity index 76% rename from examples/unsafe/input.md rename to src/unsafe.md index 903476852d..3d21cd0e72 100644 --- a/examples/unsafe/input.md +++ b/src/unsafe.md @@ -1,3 +1,5 @@ +# Unsafe Operations + As an introduction to this section, to borrow from [the official docs]( https://doc.rust-lang.org/book/unsafe.html), "one should try to minimize the amount of unsafe code in a code base." With that in mind, let's get started! @@ -17,10 +19,26 @@ always safe because they are guaranteed to point to valid data due to the borrow checker. Dereferencing a raw pointer can only be done through an unsafe block. -{pointer.rs} +```rust,editable +fn main() { + let raw_p: *const u32 = &10; + + unsafe { + assert!(*raw_p == 10); + } +} +``` ### Transmute Allows simple conversion from one type to another, however both types must have the same size and alignment: -{transmute.rs} +```rust,editable +fn main() { + let u: &[u8] = &[49, 50, 51]; + + unsafe { + assert!(u == std::mem::transmute::<&str, &[u8]>("123")); + } +} +``` \ No newline at end of file From d73f889923c630236b4e6bc79d4234ad4d6cb882 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 12:59:16 -0400 Subject: [PATCH 0635/1122] Chapter 19 --- examples/meta/doc/input.md | 19 ---------- examples/meta/test/unit_test.rs | 28 --------------- src/SUMMARY.md | 4 ++- examples/meta/input.md => src/meta.md | 2 ++ examples/meta/doc/doc.rs => src/meta/doc.md | 22 ++++++++++++ .../meta/test/input.md => src/meta/test.md | 35 +++++++++++++++++-- 6 files changed, 60 insertions(+), 50 deletions(-) delete mode 100644 examples/meta/doc/input.md delete mode 100644 examples/meta/test/unit_test.rs rename examples/meta/input.md => src/meta.md (98%) rename examples/meta/doc/doc.rs => src/meta/doc.md (57%) rename examples/meta/test/input.md => src/meta/test.md (51%) diff --git a/examples/meta/doc/input.md b/examples/meta/doc/input.md deleted file mode 100644 index 534aabfcc1..0000000000 --- a/examples/meta/doc/input.md +++ /dev/null @@ -1,19 +0,0 @@ -Doc comments are very useful for big projects that require documentation. When -running [Rustdoc][1], these are the comments that get compiled into -documentation. They are denoted by a `///`, and support [Markdown][2]. - -{doc.play} - -To run the tests, first build the code as a library, then tell rustdoc where -to find the library so it can link it into each doctest program: - -``` -rustc doc.rs --crate-type lib -rustdoc --test --extern doc="libdoc.rlib" doc.rs -``` - -(When you run `cargo test` on a library crate, Cargo will automatically -generate and run the correct rustc and rustdoc commands.) - -[1]: https://doc.rust-lang.org/book/documentation.html -[2]: https://en.wikipedia.org/wiki/Markdown diff --git a/examples/meta/test/unit_test.rs b/examples/meta/test/unit_test.rs deleted file mode 100644 index 3a70c08e1f..0000000000 --- a/examples/meta/test/unit_test.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Conditionally compile `main` only when the test-suite is *not* being run. -#[cfg(not(test))] -fn main() { - println!("If you see this, the tests were not compiled nor ran!"); -} - -// Conditionally compile the module `test` only when the test-suite is run. -#[cfg(test)] -mod test { - // A helper function `distance_test` will need. - fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { - ( - (b.0 - a.0).powi(2) + - (b.1 - a.1).powi(2) - ).sqrt() - } - - #[test] - fn distance_test() { - assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt()); - } - - #[test] - #[should_panic] - fn failing_test() { - assert!(1i32 == 2i32); - } -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 39341a594a..4532fd1ee7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -65,6 +65,8 @@ - [Std misc]() -- [Meta]() +- [Meta](meta.md) + - [Documentation](meta/doc.md) + - [Testing](meta/test.md) - [Unsafe Operations](unsafe.md) \ No newline at end of file diff --git a/examples/meta/input.md b/src/meta.md similarity index 98% rename from examples/meta/input.md rename to src/meta.md index c9c048eb9f..f5119d5f41 100644 --- a/examples/meta/input.md +++ b/src/meta.md @@ -1,3 +1,5 @@ +# Meta + Some topics aren't exactly relevant to how you program but provide you tooling or infrastructure support which just makes things better for everyone. These topics include: diff --git a/examples/meta/doc/doc.rs b/src/meta/doc.md similarity index 57% rename from examples/meta/doc/doc.rs rename to src/meta/doc.md index 9fa7edbd3e..0c574462e3 100644 --- a/examples/meta/doc/doc.rs +++ b/src/meta/doc.md @@ -1,3 +1,10 @@ +# Documentation + +Doc comments are very useful for big projects that require documentation. When +running [Rustdoc][1], these are the comments that get compiled into +documentation. They are denoted by a `///`, and support [Markdown][2]. + +```rust,editable #![crate_name = "doc"] /// A human being is represented here @@ -40,3 +47,18 @@ fn main() { john.hello(); } +``` + +To run the tests, first build the code as a library, then tell rustdoc where +to find the library so it can link it into each doctest program: + +```bash +$ rustc doc.rs --crate-type lib +$ rustdoc --test --extern doc="libdoc.rlib" doc.rs +``` + +(When you run `cargo test` on a library crate, Cargo will automatically +generate and run the correct rustc and rustdoc commands.) + +[1]: https://doc.rust-lang.org/book/documentation.html +[2]: https://en.wikipedia.org/wiki/Markdown \ No newline at end of file diff --git a/examples/meta/test/input.md b/src/meta/test.md similarity index 51% rename from examples/meta/test/input.md rename to src/meta/test.md index 31237d6c9d..8eb410f287 100644 --- a/examples/meta/test/input.md +++ b/src/meta/test.md @@ -1,14 +1,45 @@ +# Testing + Functions can be tested by using these [attributes][attributes]: * `#[test]` marks a function as a unit test. The function must take zero parameters and return nothing. * `#[should_panic]` marks a function as a panicking test. -{unit_test.rs} +```rust,editable +// Conditionally compile `main` only when the test-suite is *not* being run. +#[cfg(not(test))] +fn main() { + println!("If you see this, the tests were not compiled nor ran!"); +} -Tests can be run with `cargo test` or `rustc --test`. +// Conditionally compile the module `test` only when the test-suite is run. +#[cfg(test)] +mod test { + // A helper function `distance_test` will need. + fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { + ( + (b.0 - a.0).powi(2) + + (b.1 - a.1).powi(2) + ).sqrt() + } + #[test] + fn distance_test() { + assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt()); + } + + #[test] + #[should_panic] + fn failing_test() { + assert!(1i32 == 2i32); + } +} ``` + +Tests can be run with `cargo test` or `rustc --test`. + +```bash $ rustc --test unit_test.rs $ ./unit_test From 7478682c7087546581f51b90ce3d3cf1a1f845a1 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 13:11:23 -0400 Subject: [PATCH 0636/1122] Chapter 9 --- examples/mod/split/input.md | 33 ------- examples/mod/split/my/inaccessible.rs | 4 - examples/mod/split/my/mod.rs | 19 ---- examples/mod/split/my/nested.rs | 8 -- examples/mod/split/split.rs | 17 ---- examples/mod/struct_visibility/input.md | 13 --- examples/mod/super/input.md | 4 - examples/mod/use/input.md | 4 - examples/mod/visibility/input.md | 5 - src/SUMMARY.md | 7 +- examples/mod/input.md => src/mod.md | 4 +- src/mod/split.md | 96 +++++++++++++++++++ .../struct.rs => src/mod/struct_visibility.md | 16 ++++ .../mod/super/super.rs => src/mod/super.md | 7 ++ examples/mod/use/use.rs => src/mod/use.md | 7 ++ .../visibility.rs => src/mod/visibility.md | 10 +- 16 files changed, 144 insertions(+), 110 deletions(-) delete mode 100644 examples/mod/split/input.md delete mode 100644 examples/mod/split/my/inaccessible.rs delete mode 100644 examples/mod/split/my/mod.rs delete mode 100644 examples/mod/split/my/nested.rs delete mode 100644 examples/mod/split/split.rs delete mode 100644 examples/mod/struct_visibility/input.md delete mode 100644 examples/mod/super/input.md delete mode 100644 examples/mod/use/input.md delete mode 100644 examples/mod/visibility/input.md rename examples/mod/input.md => src/mod.md (87%) create mode 100644 src/mod/split.md rename examples/mod/struct_visibility/struct.rs => src/mod/struct_visibility.md (75%) rename examples/mod/super/super.rs => src/mod/super.md (87%) rename examples/mod/use/use.rs => src/mod/use.md (85%) rename examples/mod/visibility/visibility.rs => src/mod/visibility.md (94%) diff --git a/examples/mod/split/input.md b/examples/mod/split/input.md deleted file mode 100644 index d2a7d2c237..0000000000 --- a/examples/mod/split/input.md +++ /dev/null @@ -1,33 +0,0 @@ -Modules can be mapped to a file/directory hierarchy. Let's break down the -[visibility example][visibility] in files: - -``` -$ tree . -. -|-- my -| |-- inaccessible.rs -| |-- mod.rs -| `-- nested.rs -`-- split.rs -``` - -{split.rs} - -{my/mod.rs} - -{my/nested.rs} - -{my/inaccessible.rs} - -Let's check that things still work as before: - -``` -$ rustc split.rs && ./split -called `my::function()` -called `function()` -called `my::indirect_access()`, that -> called `my::private_function()` -called `my::nested::function()` -``` - -[visibility]: /mod/visibility.html diff --git a/examples/mod/split/my/inaccessible.rs b/examples/mod/split/my/inaccessible.rs deleted file mode 100644 index 487a10e468..0000000000 --- a/examples/mod/split/my/inaccessible.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[allow(dead_code)] -pub fn public_function() { - println!("called `my::inaccessible::public_function()`"); -} diff --git a/examples/mod/split/my/mod.rs b/examples/mod/split/my/mod.rs deleted file mode 100644 index 5851229632..0000000000 --- a/examples/mod/split/my/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Similarly `mod inaccessible` and `mod nested` will locate the `nested.rs` -// and `inaccessible.rs` files and insert them here under their respective -// modules -mod inaccessible; -pub mod nested; - -pub fn function() { - println!("called `my::function()`"); -} - -fn private_function() { - println!("called `my::private_function()`"); -} - -pub fn indirect_access() { - print!("called `my::indirect_access()`, that\n> "); - - private_function(); -} diff --git a/examples/mod/split/my/nested.rs b/examples/mod/split/my/nested.rs deleted file mode 100644 index e47cf9b07b..0000000000 --- a/examples/mod/split/my/nested.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub fn function() { - println!("called `my::nested::function()`"); -} - -#[allow(dead_code)] -fn private_function() { - println!("called `my::nested::private_function()`"); -} diff --git a/examples/mod/split/split.rs b/examples/mod/split/split.rs deleted file mode 100644 index 812ff8042a..0000000000 --- a/examples/mod/split/split.rs +++ /dev/null @@ -1,17 +0,0 @@ -// This declaration will look for a file named `my.rs` or `my/mod.rs` and will -// insert its contents inside a module named `my` under this scope -mod my; - -fn function() { - println!("called `function()`"); -} - -fn main() { - my::function(); - - function(); - - my::indirect_access(); - - my::nested::function(); -} diff --git a/examples/mod/struct_visibility/input.md b/examples/mod/struct_visibility/input.md deleted file mode 100644 index fbd356cd4e..0000000000 --- a/examples/mod/struct_visibility/input.md +++ /dev/null @@ -1,13 +0,0 @@ -Structs have an extra level of visibility with their fields. The visibility -defaults to private, and can be overridden with the `pub` modifier. This -visibility only matters when a struct is accessed from outside the module -where it is defined, and has the goal of hiding information (encapsulation). - -{struct.play} - -### See also: - -[generics][generics] and [methods][methods] - -[generics]: /generics.html -[methods]: /fn/methods.html \ No newline at end of file diff --git a/examples/mod/super/input.md b/examples/mod/super/input.md deleted file mode 100644 index 966ed166fb..0000000000 --- a/examples/mod/super/input.md +++ /dev/null @@ -1,4 +0,0 @@ -The `super` and `self` keywords can be used in the path to remove ambiguity -when accessing items and to prevent unnecessary hardcoding of paths. - -{super.play} diff --git a/examples/mod/use/input.md b/examples/mod/use/input.md deleted file mode 100644 index 05b3657427..0000000000 --- a/examples/mod/use/input.md +++ /dev/null @@ -1,4 +0,0 @@ -The `use` declaration can be used to bind a full path to a new name, for easier -access. - -{use.play} diff --git a/examples/mod/visibility/input.md b/examples/mod/visibility/input.md deleted file mode 100644 index b334d7625e..0000000000 --- a/examples/mod/visibility/input.md +++ /dev/null @@ -1,5 +0,0 @@ -By default, the items in a module have private visibility, but this can be -overridden with the `pub` modifier. Only the public items of a module can be -accessed from outside the module scope. - -{visibility.play} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4532fd1ee7..5f97efe440 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -39,7 +39,12 @@ - [Functions]() -- [Modules]() +- [Modules](mod.md) + - [Visibility](mod/visibility.md) + - [Struct visibility](mod/struct_visibility.md) + - [The `use` declaration](mod/use.md) + - [`super` and `self`](mod/super.md) + - [File hierarchy](mod/split.md) - [Crates](crates.md) - [Library](crates/lib.md) diff --git a/examples/mod/input.md b/src/mod.md similarity index 87% rename from examples/mod/input.md rename to src/mod.md index d9d42576f9..f9a1183486 100644 --- a/examples/mod/input.md +++ b/src/mod.md @@ -1,6 +1,8 @@ +# Modules + Rust provides a powerful module system that can be used to hierarchically split code in logical units (modules), and manage visibility (public/private) between them. A module is a collection of items: functions, structs, traits, `impl` blocks, -and even other modules. +and even other modules. \ No newline at end of file diff --git a/src/mod/split.md b/src/mod/split.md new file mode 100644 index 0000000000..b6a0ede8ce --- /dev/null +++ b/src/mod/split.md @@ -0,0 +1,96 @@ +# File hierarchy + +Modules can be mapped to a file/directory hierarchy. Let's break down the +[visibility example][visibility] in files: + +```text +$ tree . +. +|-- my +| |-- inaccessible.rs +| |-- mod.rs +| `-- nested.rs +`-- split.rs +``` + +In `split.rs`: + +```rust +// This declaration will look for a file named `my.rs` or `my/mod.rs` and will +// insert its contents inside a module named `my` under this scope +mod my; + +fn function() { + println!("called `function()`"); +} + +fn main() { + my::function(); + + function(); + + my::indirect_access(); + + my::nested::function(); +} + +``` + +In `my/mod.rs`: + +```rust +// Similarly `mod inaccessible` and `mod nested` will locate the `nested.rs` +// and `inaccessible.rs` files and insert them here under their respective +// modules +mod inaccessible; +pub mod nested; + +pub fn function() { + println!("called `my::function()`"); +} + +fn private_function() { + println!("called `my::private_function()`"); +} + +pub fn indirect_access() { + print!("called `my::indirect_access()`, that\n> "); + + private_function(); +} +``` + +In `my/nested.rs`: + +```rust +pub fn function() { + println!("called `my::nested::function()`"); +} + +#[allow(dead_code)] +fn private_function() { + println!("called `my::nested::private_function()`"); +} +``` + +In `my/inaccessible.rs`: + +```rust +#[allow(dead_code)] +pub fn public_function() { + println!("called `my::inaccessible::public_function()`"); +} +``` + +Let's check that things still work as before: + +```bash +$ rustc split.rs && ./split +called `my::function()` +called `function()` +called `my::indirect_access()`, that +> called `my::private_function()` +called `my::nested::function()` +``` + +[visibility]: /mod/visibility.html \ No newline at end of file diff --git a/examples/mod/struct_visibility/struct.rs b/src/mod/struct_visibility.md similarity index 75% rename from examples/mod/struct_visibility/struct.rs rename to src/mod/struct_visibility.md index bc91ec1773..d365355374 100644 --- a/examples/mod/struct_visibility/struct.rs +++ b/src/mod/struct_visibility.md @@ -1,3 +1,11 @@ +# Struct visibility + +Structs have an extra level of visibility with their fields. The visibility +defaults to private, and can be overridden with the `pub` modifier. This +visibility only matters when a struct is accessed from outside the module +where it is defined, and has the goal of hiding information (encapsulation). + +```rust,editable mod my { // A public struct with a public field of generic type `T` pub struct OpenBox { @@ -41,3 +49,11 @@ fn main() { //println!("The closed box contains: {}", _closed_box.contents); // TODO ^ Try uncommenting this line } +``` + +### See also: + +[generics][generics] and [methods][methods] + +[generics]: /generics.html +[methods]: /fn/methods.html \ No newline at end of file diff --git a/examples/mod/super/super.rs b/src/mod/super.md similarity index 87% rename from examples/mod/super/super.rs rename to src/mod/super.md index b882abcec7..c0088808be 100644 --- a/examples/mod/super/super.rs +++ b/src/mod/super.md @@ -1,3 +1,9 @@ +# `super` and `self` + +The `super` and `self` keywords can be used in the path to remove ambiguity +when accessing items and to prevent unnecessary hardcoding of paths. + +```rust,editable fn function() { println!("called `function()`"); } @@ -47,3 +53,4 @@ mod my { fn main() { my::indirect_call(); } +``` \ No newline at end of file diff --git a/examples/mod/use/use.rs b/src/mod/use.md similarity index 85% rename from examples/mod/use/use.rs rename to src/mod/use.md index 0f46965807..658c342e08 100644 --- a/examples/mod/use/use.rs +++ b/src/mod/use.md @@ -1,3 +1,9 @@ +# The `use` declaration + +The `use` declaration can be used to bind a full path to a new name, for easier +access. + +```rust,editable // Bind the `deeply::nested::function` path to `other_function`. use deeply::nested::function as other_function; @@ -31,3 +37,4 @@ fn main() { function(); } +``` \ No newline at end of file diff --git a/examples/mod/visibility/visibility.rs b/src/mod/visibility.md similarity index 94% rename from examples/mod/visibility/visibility.rs rename to src/mod/visibility.md index 4f4115f450..6345630108 100644 --- a/examples/mod/visibility/visibility.rs +++ b/src/mod/visibility.md @@ -1,3 +1,10 @@ +# Visibility + +By default, the items in a module have private visibility, but this can be +overridden with the `pub` modifier. Only the public items of a module can be +accessed from outside the module scope. + +```rust,editable // A module named `my_mod` mod my_mod { // Items in modules default to private visibility. @@ -106,4 +113,5 @@ fn main() { // Error! `private_nested` is a private module //my_mod::private_nested::function(); // TODO ^ Try uncommenting this line -} \ No newline at end of file +} +``` \ No newline at end of file From 7d890dfccc1715a2894155de17b06bdffc5c7ea0 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 16:35:10 -0400 Subject: [PATCH 0637/1122] fill out the rest of the TOC --- src/SUMMARY.md | 134 +++++++++++++++--- src/error.md | 1 + src/error/boxing_errors.md | 1 + src/error/define_error_type.md | 1 + src/error/multiple_error_types.md | 1 + .../multiple_error_types/early_returns.md | 1 + src/error/multiple_error_types/enter_try.md | 1 + src/error/option_unwrap.md | 1 + src/error/option_unwrap/and_then.md | 1 + src/error/option_unwrap/map.md | 1 + src/error/panic.md | 1 + src/error/reenter_try.md | 1 + src/error/result.md | 1 + src/error/result/result_alias.md | 1 + src/error/result/result_map.md | 1 + src/flow_control.md | 1 + src/flow_control/for.md | 1 + src/flow_control/if_else.md | 1 + src/flow_control/if_let.md | 1 + src/flow_control/loop.md | 1 + src/flow_control/loop/nested.md | 1 + src/flow_control/loop/return.md | 1 + src/flow_control/match.md | 1 + src/flow_control/match/binding.md | 1 + src/flow_control/match/destructuring.md | 1 + .../match/destructuring/destructure_enum.md | 1 + .../destructuring/destructure_pointers.md | 1 + .../destructuring/destructure_structures.md | 1 + .../match/destructuring/destructure_tuple.md | 1 + src/flow_control/match/guard.md | 1 + src/flow_control/while.md | 1 + src/flow_control/while_let.md | 1 + src/fn.md | 1 + src/fn/closures.md | 1 + src/fn/closures/anonymity.md | 1 + src/fn/closures/capture.md | 1 + src/fn/closures/closure_examples.md | 1 + src/fn/closures/closure_examples/iter_any.md | 1 + src/fn/closures/closure_examples/iter_find.md | 1 + src/fn/closures/input_functions.md | 1 + src/fn/closures/input_parameters.md | 1 + src/fn/closures/output_parameters.md | 1 + src/fn/hof.md | 1 + src/fn/methods.md | 1 + src/generics.md | 1 + src/generics/assoc_items.md | 1 + src/generics/assoc_items/the_problem.md | 1 + src/generics/assoc_items/types.md | 1 + src/generics/bounds.md | 1 + src/generics/bounds/testcase_empty.md | 1 + src/generics/gen_fn.md | 1 + src/generics/gen_trait.md | 1 + src/generics/impl.md | 1 + src/generics/multi_bounds.md | 1 + src/generics/phantom.md | 1 + src/generics/phantom/testcase_units.md | 1 + src/generics/where.md | 1 + src/macros.md | 1 + src/macros/designators.md | 1 + src/macros/dry.md | 1 + src/macros/overload.md | 1 + src/macros/repeat.md | 1 + src/scope.md | 1 + src/scope/borrow.md | 1 + src/scope/borrowing/alias.md | 1 + src/scope/borrowing/freeze.md | 1 + src/scope/borrowing/mut.md | 1 + src/scope/borrowing/ref.md | 1 + src/scope/lifetime.md | 1 + src/scope/lifetime/elision.md | 1 + src/scope/lifetime/explicit.md | 1 + src/scope/lifetime/fn.md | 1 + src/scope/lifetime/lifetime_bounds.md | 1 + src/scope/lifetime/lifetime_coercion.md | 1 + src/scope/lifetime/methods.md | 1 + src/scope/lifetime/static_lifetime.md | 1 + src/scope/lifetime/struct.md | 1 + src/scope/move.md | 1 + src/scope/move/mut.md | 1 + src/scope/raii.md | 1 + src/std.md | 1 + src/std/alt_key_types.md | 1 + src/std/box.md | 1 + src/std/hash.md | 1 + src/std/hashset.md | 1 + src/std/option.md | 1 + src/std/panic.md | 1 + src/std/result.md | 1 + src/std/str.md | 1 + src/std/try.md | 1 + src/std/vec.md | 1 + src/std_misc.md | 1 + src/std_misc/arg.md | 1 + src/std_misc/arg/matching.md | 1 + src/std_misc/channels.md | 1 + src/std_misc/ffi.md | 1 + src/std_misc/file.md | 1 + src/std_misc/file/create.md | 1 + src/std_misc/file/open.md | 1 + src/std_misc/fs.md | 1 + src/std_misc/path.md | 1 + src/std_misc/process.md | 1 + src/std_misc/process/pipe.md | 1 + src/std_misc/process/wait.md | 1 + src/std_misc/threads.md | 1 + src/std_misc/threads/testcase_mapreduce.md | 1 + src/trait.md | 1 + src/trait/clone.md | 1 + src/trait/derive.md | 1 + src/trait/drop.md | 1 + src/trait/iter.md | 1 + src/trait/ops.md | 1 + 112 files changed, 229 insertions(+), 16 deletions(-) create mode 100644 src/error.md create mode 100644 src/error/boxing_errors.md create mode 100644 src/error/define_error_type.md create mode 100644 src/error/multiple_error_types.md create mode 100644 src/error/multiple_error_types/early_returns.md create mode 100644 src/error/multiple_error_types/enter_try.md create mode 100644 src/error/option_unwrap.md create mode 100644 src/error/option_unwrap/and_then.md create mode 100644 src/error/option_unwrap/map.md create mode 100644 src/error/panic.md create mode 100644 src/error/reenter_try.md create mode 100644 src/error/result.md create mode 100644 src/error/result/result_alias.md create mode 100644 src/error/result/result_map.md create mode 100644 src/flow_control.md create mode 100644 src/flow_control/for.md create mode 100644 src/flow_control/if_else.md create mode 100644 src/flow_control/if_let.md create mode 100644 src/flow_control/loop.md create mode 100644 src/flow_control/loop/nested.md create mode 100644 src/flow_control/loop/return.md create mode 100644 src/flow_control/match.md create mode 100644 src/flow_control/match/binding.md create mode 100644 src/flow_control/match/destructuring.md create mode 100644 src/flow_control/match/destructuring/destructure_enum.md create mode 100644 src/flow_control/match/destructuring/destructure_pointers.md create mode 100644 src/flow_control/match/destructuring/destructure_structures.md create mode 100644 src/flow_control/match/destructuring/destructure_tuple.md create mode 100644 src/flow_control/match/guard.md create mode 100644 src/flow_control/while.md create mode 100644 src/flow_control/while_let.md create mode 100644 src/fn.md create mode 100644 src/fn/closures.md create mode 100644 src/fn/closures/anonymity.md create mode 100644 src/fn/closures/capture.md create mode 100644 src/fn/closures/closure_examples.md create mode 100644 src/fn/closures/closure_examples/iter_any.md create mode 100644 src/fn/closures/closure_examples/iter_find.md create mode 100644 src/fn/closures/input_functions.md create mode 100644 src/fn/closures/input_parameters.md create mode 100644 src/fn/closures/output_parameters.md create mode 100644 src/fn/hof.md create mode 100644 src/fn/methods.md create mode 100644 src/generics.md create mode 100644 src/generics/assoc_items.md create mode 100644 src/generics/assoc_items/the_problem.md create mode 100644 src/generics/assoc_items/types.md create mode 100644 src/generics/bounds.md create mode 100644 src/generics/bounds/testcase_empty.md create mode 100644 src/generics/gen_fn.md create mode 100644 src/generics/gen_trait.md create mode 100644 src/generics/impl.md create mode 100644 src/generics/multi_bounds.md create mode 100644 src/generics/phantom.md create mode 100644 src/generics/phantom/testcase_units.md create mode 100644 src/generics/where.md create mode 100644 src/macros.md create mode 100644 src/macros/designators.md create mode 100644 src/macros/dry.md create mode 100644 src/macros/overload.md create mode 100644 src/macros/repeat.md create mode 100644 src/scope.md create mode 100644 src/scope/borrow.md create mode 100644 src/scope/borrowing/alias.md create mode 100644 src/scope/borrowing/freeze.md create mode 100644 src/scope/borrowing/mut.md create mode 100644 src/scope/borrowing/ref.md create mode 100644 src/scope/lifetime.md create mode 100644 src/scope/lifetime/elision.md create mode 100644 src/scope/lifetime/explicit.md create mode 100644 src/scope/lifetime/fn.md create mode 100644 src/scope/lifetime/lifetime_bounds.md create mode 100644 src/scope/lifetime/lifetime_coercion.md create mode 100644 src/scope/lifetime/methods.md create mode 100644 src/scope/lifetime/static_lifetime.md create mode 100644 src/scope/lifetime/struct.md create mode 100644 src/scope/move.md create mode 100644 src/scope/move/mut.md create mode 100644 src/scope/raii.md create mode 100644 src/std.md create mode 100644 src/std/alt_key_types.md create mode 100644 src/std/box.md create mode 100644 src/std/hash.md create mode 100644 src/std/hashset.md create mode 100644 src/std/option.md create mode 100644 src/std/panic.md create mode 100644 src/std/result.md create mode 100644 src/std/str.md create mode 100644 src/std/try.md create mode 100644 src/std/vec.md create mode 100644 src/std_misc.md create mode 100644 src/std_misc/arg.md create mode 100644 src/std_misc/arg/matching.md create mode 100644 src/std_misc/channels.md create mode 100644 src/std_misc/ffi.md create mode 100644 src/std_misc/file.md create mode 100644 src/std_misc/file/create.md create mode 100644 src/std_misc/file/open.md create mode 100644 src/std_misc/fs.md create mode 100644 src/std_misc/path.md create mode 100644 src/std_misc/process.md create mode 100644 src/std_misc/process/pipe.md create mode 100644 src/std_misc/process/wait.md create mode 100644 src/std_misc/threads.md create mode 100644 src/std_misc/threads/testcase_mapreduce.md create mode 100644 src/trait.md create mode 100644 src/trait/clone.md create mode 100644 src/trait/derive.md create mode 100644 src/trait/drop.md create mode 100644 src/trait/iter.md create mode 100644 src/trait/ops.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5f97efe440..1b1a1983d2 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -35,9 +35,36 @@ - [Expressions](expression.md) -- [Flow control]() - -- [Functions]() +- [Flow Control](flow_control.md) + - [if/else](flow_control/if_else.md) + - [loop](flow_control/loop.md) + - [Nesting and labels](flow_control/loop/nested.md) + - [Returning from loops](flow_control/loop/return.md) + - [while](flow_control/while.md) + - [for and range](flow_control/for.md) + - [match](flow_control/match.md) + - [Destructuring](flow_control/match/destructuring.md) + - [tuples](flow_control/match/destructuring/destructure_tuple.md) + - [enums](flow_control/match/destructuring/destructure_enum.md) + - [pointers/ref](flow_control/match/destructuring/destructure_pointers.md) + - [structs](flow_control/match/destructuring/destructure_structures.md) + - [Guards](flow_control/match/guard.md) + - [Binding](flow_control/match/binding.md) + - [if let](flow_control/if_let.md) + - [while let](flow_control/while_let.md) + +- [Functions](fn.md) + - [Methods](fn/methods.md) + - [Closures](fn/closures.md) + - [Capturing](fn/closures/capture.md) + - [As input parameters](fn/closures/input_parameters.md) + - [Type anonymity](fn/closures/anonymity.md) + - [Input functions](fn/closures/input_functions.md) + - [As output parameters](fn/closures/output_parameters.md) + - [Examples in `std`](fn/closures/closure_examples.md) + - [Iterator::any](fn/closures/closure_examples/iter_any.md) + - [Iterator::find](fn/closures/closure_examples/iter_find.md) + - [Higher Order Functions](fn/hof.md) - [Modules](mod.md) - [Visibility](mod/visibility.md) @@ -56,19 +83,94 @@ - [`cfg`](attribute/cfg.md) - [Custom](attribute/cfg/custom.md) -- [Generics]() - -- [Scoping Rules]() - -- [Traits]() - -- [macro_rules!]() - -- [Error Handling]() - -- [Std library types]() - -- [Std misc]() +- [Generics](generics.md) + - [Functions](generics/gen_fn.md) + - [Implementation](generics/impl.md) + - [Traits](generics/gen_trait.md) + - [Bounds](generics/bounds.md) + - [Testcase: empty bounds](generics/bounds/testcase_empty.md) + - [Multiple bounds](generics/multi_bounds.md) + - [Where clauses](generics/where.md) + - [Associated items](generics/assoc_items.md) + - [The Problem](generics/assoc_items/the_problem.md) + - [Associated types](generics/assoc_items/types.md) + - [Phantom type parameters](generics/phantom.md) + - [Testcase: unit clarification](generics/phantom/testcase_units.md) + +- [Scoping rules](scope.md) + - [RAII](scope/raii.md) + - [Ownership and moves](scope/move.md) + - [Mutability](scope/move/mut.md) + - [Borrowing](scope/borrow.md) + - [Mutability](scope/borrowing/mut.md) + - [Freezing](scope/borrowing/freeze.md) + - [Aliasing](scope/borrowing/alias.md) + - [The ref pattern](scope/borrowing/ref.md) + - [Lifetimes](scope/lifetime.md) + - [Explicit annotation](scope/lifetime/explicit.md) + - [Functions](scope/lifetime/fn.md) + - [Methods](scope/lifetime/methods.md) + - [Structs](scope/lifetime/struct.md) + - [Bounds](scope/lifetime/lifetime_bounds.md) + - [Coercion](scope/lifetime/lifetime_coercion.md) + - [static](scope/lifetime/static_lifetime.md) + - [elision](scope/lifetime/elision.md) + +- [Traits](trait.md) + - [Derive](trait/derive.md) + - [Operator Overloading](trait/ops.md) + - [Drop](trait/drop.md) + - [Iterators](trait/iter.md) + - [Clone](trait/clone.md) + +- [macro_rules!](macros.md) + - [Designators](macros/designators.md) + - [Overload](macros/overload.md) + - [Repeat](macros/repeat.md) + - [DRY (Don't Repeat Yourself)](macros/dry.md) + +- [Error handling](error.md) + - [`panic`](error/panic.md) + - [`Option` & `unwrap`](error/option_unwrap.md) + - [Combinators: `map`](error/option_unwrap/map.md) + - [Combinators: `and_then`](error/option_unwrap/and_then.md) + - [`Result`](error/result.md) + - [`map` for `Result`](error/result/result_map.md) + - [aliases for `Result`](error/result/result_alias.md) + - [Multiple error types](error/multiple_error_types.md) + - [Early returns](error/multiple_error_types/early_returns.md) + - [Introducing `try!`](error/multiple_error_types/enter_try.md) + - [Defining an error type](error/define_error_type.md) + - [Other uses of `try!`](error/reenter_try.md) + - [`Box`ing errors](error/boxing_errors.md) + +- [Std library types](std.md) + - [Box, stack and heap](std/box.md) + - [Vectors](std/vec.md) + - [Strings](std/str.md) + - [`Option`](std/option.md) + - [`Result`](std/result.md) + - [`try!`](std/try.md) + - [`panic!`](std/panic.md) + - [HashMap](std/hash.md) + - [Alternate/custom key types](std/alt_key_types.md) + - [HashSet](std/hashset.md) + +- [Std misc](std_misc.md) + - [Threads](std_misc/threads.md) + - [Testcase: map-reduce](std_misc/threads/testcase_mapreduce.md) + - [Channels](std_misc/channels.md) + - [Path](std_misc/path.md) + - [File I/O](std_misc/file.md) + - [`open`](std_misc/file/open.md) + - [`create`](std_misc/file/create.md) + - [Child processes](std_misc/process.md) + - [Pipes](std_misc/process/pipe.md) + - [Wait](std_misc/process/wait.md) + - [Filesystem Operations](std_misc/fs.md) + - [Program arguments](std_misc/arg.md) + - [Argument parsing](std_misc/arg/matching.md) + - [Foreign Function Interface](std_misc/ffi.md) - [Meta](meta.md) - [Documentation](meta/doc.md) diff --git a/src/error.md b/src/error.md new file mode 100644 index 0000000000..face61c6e1 --- /dev/null +++ b/src/error.md @@ -0,0 +1 @@ +# Error handling diff --git a/src/error/boxing_errors.md b/src/error/boxing_errors.md new file mode 100644 index 0000000000..578d08fc68 --- /dev/null +++ b/src/error/boxing_errors.md @@ -0,0 +1 @@ +# `Box`ing errors diff --git a/src/error/define_error_type.md b/src/error/define_error_type.md new file mode 100644 index 0000000000..ac01ddf865 --- /dev/null +++ b/src/error/define_error_type.md @@ -0,0 +1 @@ +# Defining an error type diff --git a/src/error/multiple_error_types.md b/src/error/multiple_error_types.md new file mode 100644 index 0000000000..9de84cfa32 --- /dev/null +++ b/src/error/multiple_error_types.md @@ -0,0 +1 @@ +# Multiple error types diff --git a/src/error/multiple_error_types/early_returns.md b/src/error/multiple_error_types/early_returns.md new file mode 100644 index 0000000000..c2684b0926 --- /dev/null +++ b/src/error/multiple_error_types/early_returns.md @@ -0,0 +1 @@ +# Early returns diff --git a/src/error/multiple_error_types/enter_try.md b/src/error/multiple_error_types/enter_try.md new file mode 100644 index 0000000000..5feaeda6dc --- /dev/null +++ b/src/error/multiple_error_types/enter_try.md @@ -0,0 +1 @@ +# Introducing `try!` diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md new file mode 100644 index 0000000000..825289d4dc --- /dev/null +++ b/src/error/option_unwrap.md @@ -0,0 +1 @@ +# `Option` & `unwrap` diff --git a/src/error/option_unwrap/and_then.md b/src/error/option_unwrap/and_then.md new file mode 100644 index 0000000000..c8863fc6c6 --- /dev/null +++ b/src/error/option_unwrap/and_then.md @@ -0,0 +1 @@ +# Combinators: `and_then` diff --git a/src/error/option_unwrap/map.md b/src/error/option_unwrap/map.md new file mode 100644 index 0000000000..4a650ffe43 --- /dev/null +++ b/src/error/option_unwrap/map.md @@ -0,0 +1 @@ +# Combinators: `map` diff --git a/src/error/panic.md b/src/error/panic.md new file mode 100644 index 0000000000..8d1d1a5822 --- /dev/null +++ b/src/error/panic.md @@ -0,0 +1 @@ +# `panic` diff --git a/src/error/reenter_try.md b/src/error/reenter_try.md new file mode 100644 index 0000000000..8a7f9cef8c --- /dev/null +++ b/src/error/reenter_try.md @@ -0,0 +1 @@ +# Other uses of `try!` diff --git a/src/error/result.md b/src/error/result.md new file mode 100644 index 0000000000..288cf33ef4 --- /dev/null +++ b/src/error/result.md @@ -0,0 +1 @@ +# `Result` diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md new file mode 100644 index 0000000000..7dc3bbd7c7 --- /dev/null +++ b/src/error/result/result_alias.md @@ -0,0 +1 @@ +# aliases for `Result` diff --git a/src/error/result/result_map.md b/src/error/result/result_map.md new file mode 100644 index 0000000000..a64dc9bcd3 --- /dev/null +++ b/src/error/result/result_map.md @@ -0,0 +1 @@ +# `map` for `Result` diff --git a/src/flow_control.md b/src/flow_control.md new file mode 100644 index 0000000000..cf0c99f028 --- /dev/null +++ b/src/flow_control.md @@ -0,0 +1 @@ +# Flow Control diff --git a/src/flow_control/for.md b/src/flow_control/for.md new file mode 100644 index 0000000000..abf5c8af57 --- /dev/null +++ b/src/flow_control/for.md @@ -0,0 +1 @@ +# for and range diff --git a/src/flow_control/if_else.md b/src/flow_control/if_else.md new file mode 100644 index 0000000000..148a691cb6 --- /dev/null +++ b/src/flow_control/if_else.md @@ -0,0 +1 @@ +# if/else diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md new file mode 100644 index 0000000000..72cfb74a1d --- /dev/null +++ b/src/flow_control/if_let.md @@ -0,0 +1 @@ +# if let diff --git a/src/flow_control/loop.md b/src/flow_control/loop.md new file mode 100644 index 0000000000..baff0cf997 --- /dev/null +++ b/src/flow_control/loop.md @@ -0,0 +1 @@ +# loop diff --git a/src/flow_control/loop/nested.md b/src/flow_control/loop/nested.md new file mode 100644 index 0000000000..a0653990fe --- /dev/null +++ b/src/flow_control/loop/nested.md @@ -0,0 +1 @@ +# Nesting and labels diff --git a/src/flow_control/loop/return.md b/src/flow_control/loop/return.md new file mode 100644 index 0000000000..bbde971463 --- /dev/null +++ b/src/flow_control/loop/return.md @@ -0,0 +1 @@ +# Returning from loops diff --git a/src/flow_control/match.md b/src/flow_control/match.md new file mode 100644 index 0000000000..94a04c5700 --- /dev/null +++ b/src/flow_control/match.md @@ -0,0 +1 @@ +# match diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md new file mode 100644 index 0000000000..7f93c67379 --- /dev/null +++ b/src/flow_control/match/binding.md @@ -0,0 +1 @@ +# Binding diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md new file mode 100644 index 0000000000..6c740766b1 --- /dev/null +++ b/src/flow_control/match/destructuring.md @@ -0,0 +1 @@ +# Destructuring diff --git a/src/flow_control/match/destructuring/destructure_enum.md b/src/flow_control/match/destructuring/destructure_enum.md new file mode 100644 index 0000000000..af2393bf06 --- /dev/null +++ b/src/flow_control/match/destructuring/destructure_enum.md @@ -0,0 +1 @@ +# enums diff --git a/src/flow_control/match/destructuring/destructure_pointers.md b/src/flow_control/match/destructuring/destructure_pointers.md new file mode 100644 index 0000000000..0bfff4b9b1 --- /dev/null +++ b/src/flow_control/match/destructuring/destructure_pointers.md @@ -0,0 +1 @@ +# pointers/ref diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md new file mode 100644 index 0000000000..77bb0c627b --- /dev/null +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -0,0 +1 @@ +# structs diff --git a/src/flow_control/match/destructuring/destructure_tuple.md b/src/flow_control/match/destructuring/destructure_tuple.md new file mode 100644 index 0000000000..5757bde6ad --- /dev/null +++ b/src/flow_control/match/destructuring/destructure_tuple.md @@ -0,0 +1 @@ +# tuples diff --git a/src/flow_control/match/guard.md b/src/flow_control/match/guard.md new file mode 100644 index 0000000000..ce68677ded --- /dev/null +++ b/src/flow_control/match/guard.md @@ -0,0 +1 @@ +# Guards diff --git a/src/flow_control/while.md b/src/flow_control/while.md new file mode 100644 index 0000000000..ab6710b007 --- /dev/null +++ b/src/flow_control/while.md @@ -0,0 +1 @@ +# while diff --git a/src/flow_control/while_let.md b/src/flow_control/while_let.md new file mode 100644 index 0000000000..34dd78197c --- /dev/null +++ b/src/flow_control/while_let.md @@ -0,0 +1 @@ +# while let diff --git a/src/fn.md b/src/fn.md new file mode 100644 index 0000000000..0c5faf50f8 --- /dev/null +++ b/src/fn.md @@ -0,0 +1 @@ +# Functions diff --git a/src/fn/closures.md b/src/fn/closures.md new file mode 100644 index 0000000000..713d5db4dc --- /dev/null +++ b/src/fn/closures.md @@ -0,0 +1 @@ +# Closures diff --git a/src/fn/closures/anonymity.md b/src/fn/closures/anonymity.md new file mode 100644 index 0000000000..c00413ad12 --- /dev/null +++ b/src/fn/closures/anonymity.md @@ -0,0 +1 @@ +# Type anonymity diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md new file mode 100644 index 0000000000..e297a98caa --- /dev/null +++ b/src/fn/closures/capture.md @@ -0,0 +1 @@ +# Capturing diff --git a/src/fn/closures/closure_examples.md b/src/fn/closures/closure_examples.md new file mode 100644 index 0000000000..f2dbaef2b7 --- /dev/null +++ b/src/fn/closures/closure_examples.md @@ -0,0 +1 @@ +# Examples in `std` diff --git a/src/fn/closures/closure_examples/iter_any.md b/src/fn/closures/closure_examples/iter_any.md new file mode 100644 index 0000000000..294bb8c20e --- /dev/null +++ b/src/fn/closures/closure_examples/iter_any.md @@ -0,0 +1 @@ +# Iterator::any diff --git a/src/fn/closures/closure_examples/iter_find.md b/src/fn/closures/closure_examples/iter_find.md new file mode 100644 index 0000000000..2b944b3a9d --- /dev/null +++ b/src/fn/closures/closure_examples/iter_find.md @@ -0,0 +1 @@ +# Iterator::find diff --git a/src/fn/closures/input_functions.md b/src/fn/closures/input_functions.md new file mode 100644 index 0000000000..323cfcf44e --- /dev/null +++ b/src/fn/closures/input_functions.md @@ -0,0 +1 @@ +# Input functions diff --git a/src/fn/closures/input_parameters.md b/src/fn/closures/input_parameters.md new file mode 100644 index 0000000000..61b2d9f0d6 --- /dev/null +++ b/src/fn/closures/input_parameters.md @@ -0,0 +1 @@ +# As input parameters diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md new file mode 100644 index 0000000000..1028097a4b --- /dev/null +++ b/src/fn/closures/output_parameters.md @@ -0,0 +1 @@ +# As output parameters diff --git a/src/fn/hof.md b/src/fn/hof.md new file mode 100644 index 0000000000..be7450e7fb --- /dev/null +++ b/src/fn/hof.md @@ -0,0 +1 @@ +# Higher Order Functions diff --git a/src/fn/methods.md b/src/fn/methods.md new file mode 100644 index 0000000000..8f834183a1 --- /dev/null +++ b/src/fn/methods.md @@ -0,0 +1 @@ +# Methods diff --git a/src/generics.md b/src/generics.md new file mode 100644 index 0000000000..292d26b987 --- /dev/null +++ b/src/generics.md @@ -0,0 +1 @@ +# Generics diff --git a/src/generics/assoc_items.md b/src/generics/assoc_items.md new file mode 100644 index 0000000000..d1e932f016 --- /dev/null +++ b/src/generics/assoc_items.md @@ -0,0 +1 @@ +# Associated items diff --git a/src/generics/assoc_items/the_problem.md b/src/generics/assoc_items/the_problem.md new file mode 100644 index 0000000000..0e040b4d71 --- /dev/null +++ b/src/generics/assoc_items/the_problem.md @@ -0,0 +1 @@ +# The Problem diff --git a/src/generics/assoc_items/types.md b/src/generics/assoc_items/types.md new file mode 100644 index 0000000000..a06af85e08 --- /dev/null +++ b/src/generics/assoc_items/types.md @@ -0,0 +1 @@ +# Associated types diff --git a/src/generics/bounds.md b/src/generics/bounds.md new file mode 100644 index 0000000000..b63c350b05 --- /dev/null +++ b/src/generics/bounds.md @@ -0,0 +1 @@ +# Bounds diff --git a/src/generics/bounds/testcase_empty.md b/src/generics/bounds/testcase_empty.md new file mode 100644 index 0000000000..4bcf98ee78 --- /dev/null +++ b/src/generics/bounds/testcase_empty.md @@ -0,0 +1 @@ +# Testcase: empty bounds diff --git a/src/generics/gen_fn.md b/src/generics/gen_fn.md new file mode 100644 index 0000000000..0c5faf50f8 --- /dev/null +++ b/src/generics/gen_fn.md @@ -0,0 +1 @@ +# Functions diff --git a/src/generics/gen_trait.md b/src/generics/gen_trait.md new file mode 100644 index 0000000000..445d444b17 --- /dev/null +++ b/src/generics/gen_trait.md @@ -0,0 +1 @@ +# Traits diff --git a/src/generics/impl.md b/src/generics/impl.md new file mode 100644 index 0000000000..d2557ff700 --- /dev/null +++ b/src/generics/impl.md @@ -0,0 +1 @@ +# Implementation diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md new file mode 100644 index 0000000000..807c9546f4 --- /dev/null +++ b/src/generics/multi_bounds.md @@ -0,0 +1 @@ +# Multiple bounds diff --git a/src/generics/phantom.md b/src/generics/phantom.md new file mode 100644 index 0000000000..f5ef5bc689 --- /dev/null +++ b/src/generics/phantom.md @@ -0,0 +1 @@ +# Phantom type parameters diff --git a/src/generics/phantom/testcase_units.md b/src/generics/phantom/testcase_units.md new file mode 100644 index 0000000000..012cd5c6eb --- /dev/null +++ b/src/generics/phantom/testcase_units.md @@ -0,0 +1 @@ +# Testcase: unit clarification diff --git a/src/generics/where.md b/src/generics/where.md new file mode 100644 index 0000000000..6b877a2089 --- /dev/null +++ b/src/generics/where.md @@ -0,0 +1 @@ +# Where clauses diff --git a/src/macros.md b/src/macros.md new file mode 100644 index 0000000000..695221abf8 --- /dev/null +++ b/src/macros.md @@ -0,0 +1 @@ +# macro_rules! diff --git a/src/macros/designators.md b/src/macros/designators.md new file mode 100644 index 0000000000..b6a41ad331 --- /dev/null +++ b/src/macros/designators.md @@ -0,0 +1 @@ +# Designators diff --git a/src/macros/dry.md b/src/macros/dry.md new file mode 100644 index 0000000000..02196ef53e --- /dev/null +++ b/src/macros/dry.md @@ -0,0 +1 @@ +# DRY (Don't Repeat Yourself) diff --git a/src/macros/overload.md b/src/macros/overload.md new file mode 100644 index 0000000000..6819d74a4b --- /dev/null +++ b/src/macros/overload.md @@ -0,0 +1 @@ +# Overload diff --git a/src/macros/repeat.md b/src/macros/repeat.md new file mode 100644 index 0000000000..5f50dadb6d --- /dev/null +++ b/src/macros/repeat.md @@ -0,0 +1 @@ +# Repeat diff --git a/src/scope.md b/src/scope.md new file mode 100644 index 0000000000..1b7c55ad2d --- /dev/null +++ b/src/scope.md @@ -0,0 +1 @@ +# Scoping rules diff --git a/src/scope/borrow.md b/src/scope/borrow.md new file mode 100644 index 0000000000..dda14f3782 --- /dev/null +++ b/src/scope/borrow.md @@ -0,0 +1 @@ +# Borrowing diff --git a/src/scope/borrowing/alias.md b/src/scope/borrowing/alias.md new file mode 100644 index 0000000000..81497a63e9 --- /dev/null +++ b/src/scope/borrowing/alias.md @@ -0,0 +1 @@ +# Aliasing diff --git a/src/scope/borrowing/freeze.md b/src/scope/borrowing/freeze.md new file mode 100644 index 0000000000..1873d01d8e --- /dev/null +++ b/src/scope/borrowing/freeze.md @@ -0,0 +1 @@ +# Freezing diff --git a/src/scope/borrowing/mut.md b/src/scope/borrowing/mut.md new file mode 100644 index 0000000000..b2197b1cec --- /dev/null +++ b/src/scope/borrowing/mut.md @@ -0,0 +1 @@ +# Mutability diff --git a/src/scope/borrowing/ref.md b/src/scope/borrowing/ref.md new file mode 100644 index 0000000000..eda4649c45 --- /dev/null +++ b/src/scope/borrowing/ref.md @@ -0,0 +1 @@ +# The ref pattern diff --git a/src/scope/lifetime.md b/src/scope/lifetime.md new file mode 100644 index 0000000000..130cd9f700 --- /dev/null +++ b/src/scope/lifetime.md @@ -0,0 +1 @@ +# Lifetimes diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md new file mode 100644 index 0000000000..3348a5b7f5 --- /dev/null +++ b/src/scope/lifetime/elision.md @@ -0,0 +1 @@ +# elision diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md new file mode 100644 index 0000000000..c24b3d69c9 --- /dev/null +++ b/src/scope/lifetime/explicit.md @@ -0,0 +1 @@ +# Explicit annotation diff --git a/src/scope/lifetime/fn.md b/src/scope/lifetime/fn.md new file mode 100644 index 0000000000..0c5faf50f8 --- /dev/null +++ b/src/scope/lifetime/fn.md @@ -0,0 +1 @@ +# Functions diff --git a/src/scope/lifetime/lifetime_bounds.md b/src/scope/lifetime/lifetime_bounds.md new file mode 100644 index 0000000000..b63c350b05 --- /dev/null +++ b/src/scope/lifetime/lifetime_bounds.md @@ -0,0 +1 @@ +# Bounds diff --git a/src/scope/lifetime/lifetime_coercion.md b/src/scope/lifetime/lifetime_coercion.md new file mode 100644 index 0000000000..fc095e3ce8 --- /dev/null +++ b/src/scope/lifetime/lifetime_coercion.md @@ -0,0 +1 @@ +# Coercion diff --git a/src/scope/lifetime/methods.md b/src/scope/lifetime/methods.md new file mode 100644 index 0000000000..8f834183a1 --- /dev/null +++ b/src/scope/lifetime/methods.md @@ -0,0 +1 @@ +# Methods diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md new file mode 100644 index 0000000000..c98f91218d --- /dev/null +++ b/src/scope/lifetime/static_lifetime.md @@ -0,0 +1 @@ +# static diff --git a/src/scope/lifetime/struct.md b/src/scope/lifetime/struct.md new file mode 100644 index 0000000000..c88ba870a2 --- /dev/null +++ b/src/scope/lifetime/struct.md @@ -0,0 +1 @@ +# Structs diff --git a/src/scope/move.md b/src/scope/move.md new file mode 100644 index 0000000000..4953c4f0c0 --- /dev/null +++ b/src/scope/move.md @@ -0,0 +1 @@ +# Ownership and moves diff --git a/src/scope/move/mut.md b/src/scope/move/mut.md new file mode 100644 index 0000000000..b2197b1cec --- /dev/null +++ b/src/scope/move/mut.md @@ -0,0 +1 @@ +# Mutability diff --git a/src/scope/raii.md b/src/scope/raii.md new file mode 100644 index 0000000000..a9ce14a6b1 --- /dev/null +++ b/src/scope/raii.md @@ -0,0 +1 @@ +# RAII diff --git a/src/std.md b/src/std.md new file mode 100644 index 0000000000..eab248588e --- /dev/null +++ b/src/std.md @@ -0,0 +1 @@ +# Std library types diff --git a/src/std/alt_key_types.md b/src/std/alt_key_types.md new file mode 100644 index 0000000000..d83236cd0d --- /dev/null +++ b/src/std/alt_key_types.md @@ -0,0 +1 @@ +# Alternate/custom key types diff --git a/src/std/box.md b/src/std/box.md new file mode 100644 index 0000000000..5076dc2795 --- /dev/null +++ b/src/std/box.md @@ -0,0 +1 @@ +# Box, stack and heap diff --git a/src/std/hash.md b/src/std/hash.md new file mode 100644 index 0000000000..96e549de56 --- /dev/null +++ b/src/std/hash.md @@ -0,0 +1 @@ +# HashMap diff --git a/src/std/hashset.md b/src/std/hashset.md new file mode 100644 index 0000000000..3a3bcd06d5 --- /dev/null +++ b/src/std/hashset.md @@ -0,0 +1 @@ +# HashSet diff --git a/src/std/option.md b/src/std/option.md new file mode 100644 index 0000000000..b4c6002621 --- /dev/null +++ b/src/std/option.md @@ -0,0 +1 @@ +# `Option` diff --git a/src/std/panic.md b/src/std/panic.md new file mode 100644 index 0000000000..82254a157a --- /dev/null +++ b/src/std/panic.md @@ -0,0 +1 @@ +# `panic!` diff --git a/src/std/result.md b/src/std/result.md new file mode 100644 index 0000000000..288cf33ef4 --- /dev/null +++ b/src/std/result.md @@ -0,0 +1 @@ +# `Result` diff --git a/src/std/str.md b/src/std/str.md new file mode 100644 index 0000000000..ed218ce9a0 --- /dev/null +++ b/src/std/str.md @@ -0,0 +1 @@ +# Strings diff --git a/src/std/try.md b/src/std/try.md new file mode 100644 index 0000000000..5db3d1e9e7 --- /dev/null +++ b/src/std/try.md @@ -0,0 +1 @@ +# `try!` diff --git a/src/std/vec.md b/src/std/vec.md new file mode 100644 index 0000000000..0399265704 --- /dev/null +++ b/src/std/vec.md @@ -0,0 +1 @@ +# Vectors diff --git a/src/std_misc.md b/src/std_misc.md new file mode 100644 index 0000000000..786e6e6a31 --- /dev/null +++ b/src/std_misc.md @@ -0,0 +1 @@ +# Std misc diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md new file mode 100644 index 0000000000..7c83fad5c3 --- /dev/null +++ b/src/std_misc/arg.md @@ -0,0 +1 @@ +# Program arguments diff --git a/src/std_misc/arg/matching.md b/src/std_misc/arg/matching.md new file mode 100644 index 0000000000..2b897c0013 --- /dev/null +++ b/src/std_misc/arg/matching.md @@ -0,0 +1 @@ +# Argument parsing diff --git a/src/std_misc/channels.md b/src/std_misc/channels.md new file mode 100644 index 0000000000..a3c35c63e0 --- /dev/null +++ b/src/std_misc/channels.md @@ -0,0 +1 @@ +# Channels diff --git a/src/std_misc/ffi.md b/src/std_misc/ffi.md new file mode 100644 index 0000000000..32a37da5f4 --- /dev/null +++ b/src/std_misc/ffi.md @@ -0,0 +1 @@ +# Foreign Function Interface diff --git a/src/std_misc/file.md b/src/std_misc/file.md new file mode 100644 index 0000000000..6c83a9a5cf --- /dev/null +++ b/src/std_misc/file.md @@ -0,0 +1 @@ +# File I/O diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md new file mode 100644 index 0000000000..93a3968731 --- /dev/null +++ b/src/std_misc/file/create.md @@ -0,0 +1 @@ +# `create` diff --git a/src/std_misc/file/open.md b/src/std_misc/file/open.md new file mode 100644 index 0000000000..485a3dad64 --- /dev/null +++ b/src/std_misc/file/open.md @@ -0,0 +1 @@ +# `open` diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md new file mode 100644 index 0000000000..57dcafcc83 --- /dev/null +++ b/src/std_misc/fs.md @@ -0,0 +1 @@ +# Filesystem Operations diff --git a/src/std_misc/path.md b/src/std_misc/path.md new file mode 100644 index 0000000000..f541fdb442 --- /dev/null +++ b/src/std_misc/path.md @@ -0,0 +1 @@ +# Path diff --git a/src/std_misc/process.md b/src/std_misc/process.md new file mode 100644 index 0000000000..71fd4ec252 --- /dev/null +++ b/src/std_misc/process.md @@ -0,0 +1 @@ +# Child processes diff --git a/src/std_misc/process/pipe.md b/src/std_misc/process/pipe.md new file mode 100644 index 0000000000..762f736df6 --- /dev/null +++ b/src/std_misc/process/pipe.md @@ -0,0 +1 @@ +# Pipes diff --git a/src/std_misc/process/wait.md b/src/std_misc/process/wait.md new file mode 100644 index 0000000000..85c3660172 --- /dev/null +++ b/src/std_misc/process/wait.md @@ -0,0 +1 @@ +# Wait diff --git a/src/std_misc/threads.md b/src/std_misc/threads.md new file mode 100644 index 0000000000..f60f3991e1 --- /dev/null +++ b/src/std_misc/threads.md @@ -0,0 +1 @@ +# Threads diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md new file mode 100644 index 0000000000..1b8d5aee08 --- /dev/null +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -0,0 +1 @@ +# Testcase: map-reduce diff --git a/src/trait.md b/src/trait.md new file mode 100644 index 0000000000..445d444b17 --- /dev/null +++ b/src/trait.md @@ -0,0 +1 @@ +# Traits diff --git a/src/trait/clone.md b/src/trait/clone.md new file mode 100644 index 0000000000..2e497b48e4 --- /dev/null +++ b/src/trait/clone.md @@ -0,0 +1 @@ +# Clone diff --git a/src/trait/derive.md b/src/trait/derive.md new file mode 100644 index 0000000000..f12a0658d3 --- /dev/null +++ b/src/trait/derive.md @@ -0,0 +1 @@ +# Derive diff --git a/src/trait/drop.md b/src/trait/drop.md new file mode 100644 index 0000000000..c6ecf823e5 --- /dev/null +++ b/src/trait/drop.md @@ -0,0 +1 @@ +# Drop diff --git a/src/trait/iter.md b/src/trait/iter.md new file mode 100644 index 0000000000..7f511b9862 --- /dev/null +++ b/src/trait/iter.md @@ -0,0 +1 @@ +# Iterators diff --git a/src/trait/ops.md b/src/trait/ops.md new file mode 100644 index 0000000000..6917574a31 --- /dev/null +++ b/src/trait/ops.md @@ -0,0 +1 @@ +# Operator Overloading From a3a182b49a40b1dfee3a4ba4d9dfdd54d607d5dc Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 16:52:48 -0400 Subject: [PATCH 0638/1122] error chapter --- examples/error/boxing_errors/boxing_errors.rs | 75 ----------- examples/error/boxing_errors/input.md | 43 ------- .../define_error_type/define_error_type.rs | 59 --------- examples/error/define_error_type/input.md | 25 ---- examples/error/input.md | 9 -- .../early_returns/early_returns.rs | 33 ----- .../early_returns/input.md | 16 --- .../multiple_error_types/enter_try/input.md | 28 ---- .../multiple_error_types/enter_try/try.rs | 27 ---- examples/error/multiple_error_types/input.md | 47 ------- .../multiple_error_types.rs | 30 ----- .../error/option_unwrap/and_then/and_then.rs | 52 -------- .../error/option_unwrap/and_then/input.md | 21 --- examples/error/option_unwrap/input.md | 26 ---- examples/error/option_unwrap/map/input.md | 22 ---- examples/error/option_unwrap/map/map.rs | 61 --------- examples/error/option_unwrap/option_unwrap.rs | 36 ------ examples/error/panic/input.md | 5 - examples/error/panic/panic.rs | 11 -- examples/error/reenter_try/input.md | 48 ------- examples/error/reenter_try/reenter_try.rs | 56 -------- examples/error/result/input.md | 33 ----- examples/error/result/result.rs | 12 -- examples/error/result/result_alias/alias.rs | 22 ---- examples/error/result/result_alias/input.md | 19 --- examples/error/result/result_map/input.md | 20 --- .../error/result/result_map/result_map.rs | 33 ----- src/error.md | 10 ++ src/error/boxing_errors.md | 120 ++++++++++++++++++ src/error/define_error_type.md | 86 +++++++++++++ src/error/multiple_error_types.md | 79 ++++++++++++ .../multiple_error_types/early_returns.md | 51 ++++++++ src/error/multiple_error_types/enter_try.md | 57 +++++++++ src/error/option_unwrap.md | 64 ++++++++++ src/error/option_unwrap/and_then.md | 75 +++++++++++ src/error/option_unwrap/map.md | 85 +++++++++++++ src/error/panic.md | 18 +++ src/error/reenter_try.md | 106 ++++++++++++++++ src/error/result.md | 47 +++++++ src/error/result/result_alias.md | 43 +++++++ src/error/result/result_map.md | 55 ++++++++ 41 files changed, 896 insertions(+), 869 deletions(-) delete mode 100644 examples/error/boxing_errors/boxing_errors.rs delete mode 100644 examples/error/boxing_errors/input.md delete mode 100644 examples/error/define_error_type/define_error_type.rs delete mode 100644 examples/error/define_error_type/input.md delete mode 100644 examples/error/input.md delete mode 100644 examples/error/multiple_error_types/early_returns/early_returns.rs delete mode 100644 examples/error/multiple_error_types/early_returns/input.md delete mode 100644 examples/error/multiple_error_types/enter_try/input.md delete mode 100644 examples/error/multiple_error_types/enter_try/try.rs delete mode 100644 examples/error/multiple_error_types/input.md delete mode 100644 examples/error/multiple_error_types/multiple_error_types.rs delete mode 100644 examples/error/option_unwrap/and_then/and_then.rs delete mode 100644 examples/error/option_unwrap/and_then/input.md delete mode 100644 examples/error/option_unwrap/input.md delete mode 100644 examples/error/option_unwrap/map/input.md delete mode 100644 examples/error/option_unwrap/map/map.rs delete mode 100644 examples/error/option_unwrap/option_unwrap.rs delete mode 100644 examples/error/panic/input.md delete mode 100644 examples/error/panic/panic.rs delete mode 100644 examples/error/reenter_try/input.md delete mode 100644 examples/error/reenter_try/reenter_try.rs delete mode 100644 examples/error/result/input.md delete mode 100644 examples/error/result/result.rs delete mode 100644 examples/error/result/result_alias/alias.rs delete mode 100644 examples/error/result/result_alias/input.md delete mode 100644 examples/error/result/result_map/input.md delete mode 100644 examples/error/result/result_map/result_map.rs diff --git a/examples/error/boxing_errors/boxing_errors.rs b/examples/error/boxing_errors/boxing_errors.rs deleted file mode 100644 index 44dfdbca05..0000000000 --- a/examples/error/boxing_errors/boxing_errors.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::error; -use std::fmt; -use std::num::ParseIntError; - -// Change the alias to `Box`. -type Result = std::result::Result>; - -#[derive(Debug)] -enum DoubleError { - EmptyVec, - Parse(ParseIntError), -} - -impl From for DoubleError { - fn from(err: ParseIntError) -> DoubleError { - DoubleError::Parse(err) - } -} - -impl fmt::Display for DoubleError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - DoubleError::Parse(ref e) => e.fmt(f), - } - } -} - -impl error::Error for DoubleError { - fn description(&self) -> &str { - match *self { - // A very short description of the error. Doesn't need to be the - // same as `Display`. - DoubleError::EmptyVec => "empty vectors not allowed", - // This already impls `Error`, so defer to its own implementation. - DoubleError::Parse(ref e) => e.description(), - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - // No underlying cause so return `None`. - DoubleError::EmptyVec => None, - // The cause is the underlying implementation error type. Is implicitly - // cast to the trait object `&error::Error`. This works because the - // underlying type already implements the `Error` trait. - DoubleError::Parse(ref e) => Some(e), - } - } -} - -fn double_first(vec: Vec<&str>) -> Result { - let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); - let parsed = try!(first.parse::()); - - Ok(2 * parsed) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(numbers)); - print(double_first(empty)); - print(double_first(strings)); -} diff --git a/examples/error/boxing_errors/input.md b/examples/error/boxing_errors/input.md deleted file mode 100644 index 029a930c13..0000000000 --- a/examples/error/boxing_errors/input.md +++ /dev/null @@ -1,43 +0,0 @@ -By implementing `Display` and `From` for our error type, we enabled -almost all of the `std` library error handling tools. However, we missed -something: the ability to easily `Box` our error type. - -The `std` library automatically converts any type that implements the -`Error` trait into the trait object `Box`, via `From`. To a -library user, this conveniently allows the following: - -```rust -fn foo(...) -> Result> { ... } -``` - -A user may use any variety of external libraries which each provide their own error -types. In order to define a valid `Result` type, the user has a few choices: - -* define a new wrapper error type around the library's error types -* convert the error types to `String` or another intermediate choice -* `Box` the error types into `Box` via type erasure - -"Boxing" the error type is a common choice. The drawback is that the -underlying error type is only known at runtime and not -[statically determined][dynamic_dispatch]. As mentioned above, all that -needs to be done is to implement the `Error` trait: - -```rust -trait Error: Debug + Display { - fn description(&self) -> &str; - fn cause(&self) -> Option<&Error>; -} -``` - -With this implementation, let's look at our most recent example. Note that -it is just as valid with the error type of `Box` as it was before -with `DoubleError`: - -{boxing_errors.play} - -### See also: - -[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] - -[dynamic_dispatch]: https://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch -[error]: https://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/error/define_error_type/define_error_type.rs b/examples/error/define_error_type/define_error_type.rs deleted file mode 100644 index dc04bce925..0000000000 --- a/examples/error/define_error_type/define_error_type.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::num::ParseIntError; -use std::fmt; - -type Result = std::result::Result; - -#[derive(Debug)] -// Define our error types. These may be customized for our error handling cases. -// Now we will be able to write our own errors, defer to an underlying error -// implementation, or do something in between. -enum DoubleError { - // We don't require any extra info to detail this error. - EmptyVec, - // We will defer to the parse error implementation for their error. - // Supplying extra info requires adding more data to the type. - Parse(ParseIntError), -} - -// Generation of an error is completely separate from how it is displayed. -// There's no need to be concerned about cluttering complex logic with the display style. -// -// Note that we don't store any extra info about the errors. This means we can't state -// which string failed to parse without modifying our types to carry that information. -impl fmt::Display for DoubleError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - // This is a wrapper, so defer to the underlying types' implementation of `fmt`. - DoubleError::Parse(ref e) => e.fmt(f), - } - } -} - -fn double_first(vec: Vec<&str>) -> Result { - vec.first() - // Change the error to our new type. - .ok_or(DoubleError::EmptyVec) - .and_then(|s| s.parse::() - // Update to the new error type here also. - .map_err(DoubleError::Parse) - .map(|i| 2 * i)) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(numbers)); - print(double_first(empty)); - print(double_first(strings)); -} diff --git a/examples/error/define_error_type/input.md b/examples/error/define_error_type/input.md deleted file mode 100644 index ffe0ad3954..0000000000 --- a/examples/error/define_error_type/input.md +++ /dev/null @@ -1,25 +0,0 @@ -Rust allows us to define our own error types. In general, a "good" error type: - -* Represents different errors with the same type -* Presents nice error messages to the user -* Is easy to compare with other types - - Good: `Err(EmptyVec)` - - Bad: `Err("Please use a vector with at least one element".to_owned())` -* Can hold information about the error - - Good: `Err(BadChar(c, position))` - - Bad: `Err("+ cannot be used here".to_owned())` - -Note that a `String` (which we've been using up to this point) fulfills the -first two criteria, but not the last two. This makes `String` errors verbose -to create and difficult to react to. It should not be necessary to pollute -logic heavy code with `String` formatting simply to display nicely. - -{define_error_type.play} - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: https://doc.rust-lang.org/std/io/type.Result.html -[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/error/input.md b/examples/error/input.md deleted file mode 100644 index 1dc5837bf3..0000000000 --- a/examples/error/input.md +++ /dev/null @@ -1,9 +0,0 @@ -Error handling is the process of handling the possibility of failure. For -example, failing to read a file and then continuing to use that *bad* input -would clearly be problematic. Noticing and explicitly managing those errors -saves the rest of the program from various pitfalls. - -For a more rigorous discussion of error handling, refer to the error -handling section in the [official book][book]. - -[book]: https://doc.rust-lang.org/book/error-handling.html diff --git a/examples/error/multiple_error_types/early_returns/early_returns.rs b/examples/error/multiple_error_types/early_returns/early_returns.rs deleted file mode 100644 index b8ce1a450d..0000000000 --- a/examples/error/multiple_error_types/early_returns/early_returns.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - let first = match vec.first() { - Some(first) => first, - None => return Err("Please use a vector with at least one element.".to_owned()) - }; - - // Double the number inside if `parse` works fine. - // Otherwise, map any errors that `parse` yields to `String`. - match first.parse::() { - Ok(i) => Ok(2 * i), - Err(e) => Err(e.to_string()), - } -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); -} \ No newline at end of file diff --git a/examples/error/multiple_error_types/early_returns/input.md b/examples/error/multiple_error_types/early_returns/input.md deleted file mode 100644 index 61f94e3c7f..0000000000 --- a/examples/error/multiple_error_types/early_returns/input.md +++ /dev/null @@ -1,16 +0,0 @@ -In the previous example, we explicitly handled the errors using combinators. -Another way to deal with this case analysis is to use a combination of -`match` statements and *early returns*. - -That is, we can simply stop executing the function and return the error if -one occurs. For some, this form of code can be easier to both read and -write. Consider this version of the previous example, rewritten using early returns: - -{early_returns.play} - -At this point, we've learned to explicitly handle errors using combinators -and early returns. While we generally want to avoid panicking, explicitly -handling all of our errors is cumbersome. - -In the next section, we'll introduce `try!` for the cases where we simply -need to `unwrap` without possibly inducing `panic`. diff --git a/examples/error/multiple_error_types/enter_try/input.md b/examples/error/multiple_error_types/enter_try/input.md deleted file mode 100644 index ce16569332..0000000000 --- a/examples/error/multiple_error_types/enter_try/input.md +++ /dev/null @@ -1,28 +0,0 @@ -Sometimes we just want the simplicity of `unwrap` without the possibility of -a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when -what we really wanted was to get the variable *out*. This is exactly the purpose of `try!`. - -Upon finding an `Err`, there are two valid actions to take: - -1. `panic!` which we already decided to try to avoid if possible -2. `return` because an `Err` means it cannot be handled - -`try!` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s -instead of `panic`s on `Err`s. Let's see how we can simplify the earlier -example that used combinators: - -{try.play} - -Note that up until now, we've been using `String`s as errors. However, they -are somewhat limiting as an error type. In the next section, we'll learn how -to make more structured and informative errors by defining their types. - -[^1]: See [re-enter try!][re_enter_try] for more details. - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: https://doc.rust-lang.org/std/io/type.Result.html -[re_enter_try]: /error/reenter_try.html diff --git a/examples/error/multiple_error_types/enter_try/try.rs b/examples/error/multiple_error_types/enter_try/try.rs deleted file mode 100644 index 5a3337bd03..0000000000 --- a/examples/error/multiple_error_types/enter_try/try.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - let first = try!(vec.first() - .ok_or("Please use a vector with at least one element.".to_owned())); - - let value = try!(first.parse::() - .map_err(|e| e.to_string())); - - Ok(2 * value) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); -} diff --git a/examples/error/multiple_error_types/input.md b/examples/error/multiple_error_types/input.md deleted file mode 100644 index b879d8cc0d..0000000000 --- a/examples/error/multiple_error_types/input.md +++ /dev/null @@ -1,47 +0,0 @@ -The previous examples have always been very convenient; `Result`s interact -with other `Result`s and `Option`s interact with other `Option`s. - -Sometimes an `Option` needs to interact with a `Result`, or a -`Result` needs to interact with a `Result`. In those -cases, we want to manage our different error types in a way that makes them -composable and easy to interact with. - -In the following code, two instances of `unwrap` generate different error -types. `Vec::first` returns an `Option`, while `parse::` returns a -`Result`: - -```rust -fn double_first(vec: Vec<&str>) -> i32 { - let first = vec.first().unwrap(); // Generate error 1 - 2 * first.parse::().unwrap() // Generate error 2 -} - -fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - println!("The first doubled is {}", double_first(empty)); - // Error 1: the input vector is empty - - println!("The first doubled is {}", double_first(strings)); - // Error 2: the element doesn't parse to a number -} -``` - -Using our knowledge of combinators, we can rewrite the above to explicitly -handle errors. Since two different types of errors can occur, we need to -convert them to a common type such as a `String`. - -To do so, we convert both the `Option` and `Result` into `Result`s, and -then map their errors to the same type: - -{multiple_error_types.play} - -In the next section, we'll see an alternate method of explicitly handling these errors. - -### See Also: - -[`Option::ok_or`][okor], [`Result::map_err`][maperr] - -[okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or -[maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err diff --git a/examples/error/multiple_error_types/multiple_error_types.rs b/examples/error/multiple_error_types/multiple_error_types.rs deleted file mode 100644 index bcc909a069..0000000000 --- a/examples/error/multiple_error_types/multiple_error_types.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - vec.first() - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - .ok_or("Please use a vector with at least one element.".to_owned()) - .and_then(|s| s.parse::() - // Map any errors that `parse` yields to `String`. - .map_err(|e| e.to_string()) - // `Result` is the new return type, - // and we can now double the number inside. - .map(|i| 2 * i)) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); -} \ No newline at end of file diff --git a/examples/error/option_unwrap/and_then/and_then.rs b/examples/error/option_unwrap/and_then/and_then.rs deleted file mode 100644 index 35dcda831c..0000000000 --- a/examples/error/option_unwrap/and_then/and_then.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow(dead_code)] - -#[derive(Debug)] enum Food { CordonBleu, Steak, Sushi } -#[derive(Debug)] enum Day { Monday, Tuesday, Wednesday } - -// We don't have the ingredients to make Sushi. -fn have_ingredients(food: Food) -> Option { - match food { - Food::Sushi => None, - _ => Some(food), - } -} - -// We have the recipe for everything except Cordon Bleu. -fn have_recipe(food: Food) -> Option { - match food { - Food::CordonBleu => None, - _ => Some(food), - } -} - -// To make a dish, we need both the ingredients and the recipe. -// We can represent the logic with a chain of `match`es: -fn cookable_v1(food: Food) -> Option { - match have_ingredients(food) { - None => None, - Some(food) => match have_recipe(food) { - None => None, - Some(food) => Some(food), - }, - } -} - -// This can conveniently be rewritten more compactly with `and_then()`: -fn cookable_v2(food: Food) -> Option { - have_ingredients(food).and_then(have_recipe) -} - -fn eat(food: Food, day: Day) { - match cookable_v2(food) { - Some(food) => println!("Yay! On {:?} we get to eat {:?}.", day, food), - None => println!("Oh no. We don't get to eat on {:?}?", day), - } -} - -fn main() { - let (cordon_bleu, steak, sushi) = (Food::CordonBleu, Food::Steak, Food::Sushi); - - eat(cordon_bleu, Day::Monday); - eat(steak, Day::Tuesday); - eat(sushi, Day::Wednesday); -} diff --git a/examples/error/option_unwrap/and_then/input.md b/examples/error/option_unwrap/and_then/input.md deleted file mode 100644 index 8899229a06..0000000000 --- a/examples/error/option_unwrap/and_then/input.md +++ /dev/null @@ -1,21 +0,0 @@ -`map()` was described as a chainable way to simplify `match` statements. -However, using `map()` on a function that returns an `Option` results -in the nested `Option>`. Chaining multiple calls together can -then become confusing. That's where another combinator called `and_then()`, -known in some languages as flatmap, comes in. - -`and_then()` calls its function input with the wrapped value and returns the result. If the `Option` is `None`, then it returns `None` instead. - -In the following example, `cookable_v2()` results in an `Option`. -Using `map()` instead of `and_then()` would have given an -`Option>`, which is an invalid type for `eat()`. - -{and_then.play} - -### See also: - -[closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] - -[closures]: /fn/closures.html -[option]: https://doc.rust-lang.org/std/option/enum.Option.html -[and_then]: https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/option_unwrap/input.md b/examples/error/option_unwrap/input.md deleted file mode 100644 index 0070be2751..0000000000 --- a/examples/error/option_unwrap/input.md +++ /dev/null @@ -1,26 +0,0 @@ -In the last example, we showed that we can induce program failure at will. -We told our program to `panic` if the princess received an inappropriate -gift - a snake. But what if the princess expected a gift and didn't receive -one? That case would be just as bad, so it needs to be handled! - -We *could* test this against the null string (`""`) as we do with a snake. -Since we're using Rust, let's instead have the compiler point out cases -where there's no gift. - -An `enum` called `Option` in the `std` library is used when absence is a -possibility. It manifests itself as one of two "options": - -* `Some(T)`: An element of type `T` was found -* `None`: No element was found - -These cases can either be explicitly handled via `match` or implicitly with -`unwrap`. Implicit handling will either return the inner element or `panic`. - -Note that it's possible to manually customize `panic` with [expect][expect], -but `unwrap` otherwise leaves us with a less meaningful output than explicit -handling. In the following example, explicit handling yields a more -controlled result while retaining the option to `panic` if desired. - -{option_unwrap.play} - -[expect]: https://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/option_unwrap/map/input.md b/examples/error/option_unwrap/map/input.md deleted file mode 100644 index ee8b481070..0000000000 --- a/examples/error/option_unwrap/map/input.md +++ /dev/null @@ -1,22 +0,0 @@ -`match` is a valid method for handling `Option`s. However, you may -eventually find heavy usage tedious, especially with operations only valid -with an input. In these cases, [combinators][combinators] can be used to -manage control flow in a modular fashion. - -`Option` has a built in method called `map()`, a combinator for the simple -mapping of `Some -> Some` and `None -> None`. Multiple `map()` calls can be -chained together for even more flexibility. - -In the following example, `process()` replaces all functions previous -to it while staying compact. - -{map.play} - -### See also: - -[closures][closures], [`Option`][option], [`Option::map()`][map] - -[combinators]: https://doc.rust-lang.org/book/glossary.html#combinators -[closures]: /fn/closures.html -[option]: https://doc.rust-lang.org/std/option/enum.Option.html -[map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/examples/error/option_unwrap/map/map.rs b/examples/error/option_unwrap/map/map.rs deleted file mode 100644 index e851bf979a..0000000000 --- a/examples/error/option_unwrap/map/map.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![allow(dead_code)] - -#[derive(Debug)] enum Food { Apple, Carrot, Potato } - -#[derive(Debug)] struct Peeled(Food); -#[derive(Debug)] struct Chopped(Food); -#[derive(Debug)] struct Cooked(Food); - -// Peeling food. If there isn't any, then return `None`. -// Otherwise, return the peeled food. -fn peel(food: Option) -> Option { - match food { - Some(food) => Some(Peeled(food)), - None => None, - } -} - -// Chopping food. If there isn't any, then return `None`. -// Otherwise, return the chopped food. -fn chop(peeled: Option) -> Option { - match peeled { - Some(Peeled(food)) => Some(Chopped(food)), - None => None, - } -} - -// Cooking food. Here, we showcase `map()` instead of `match` for case handling. -fn cook(chopped: Option) -> Option { - chopped.map(|Chopped(food)| Cooked(food)) -} - -// A function to peel, chop, and cook food all in sequence. -// We chain multiple uses of `map()` to simplify the code. -fn process(food: Option) -> Option { - food.map(|f| Peeled(f)) - .map(|Peeled(f)| Chopped(f)) - .map(|Chopped(f)| Cooked(f)) -} - -// Check whether there's food or not before trying to eat it! -fn eat(food: Option) { - match food { - Some(food) => println!("Mmm. I love {:?}", food), - None => println!("Oh no! It wasn't edible."), - } -} - -fn main() { - let apple = Some(Food::Apple); - let carrot = Some(Food::Carrot); - let potato = None; - - let cooked_apple = cook(chop(peel(apple))); - let cooked_carrot = cook(chop(peel(carrot))); - // Let's try the simpler looking `process()` now. - let cooked_potato = process(potato); - - eat(cooked_apple); - eat(cooked_carrot); - eat(cooked_potato); -} diff --git a/examples/error/option_unwrap/option_unwrap.rs b/examples/error/option_unwrap/option_unwrap.rs deleted file mode 100644 index 8ac6ad50fb..0000000000 --- a/examples/error/option_unwrap/option_unwrap.rs +++ /dev/null @@ -1,36 +0,0 @@ -// The commoner has seen it all, and can handle any gift well. -// All gifts are handled explicitly using `match`. -fn give_commoner(gift: Option<&str>) { - // Specify a course of action for each case. - match gift { - Some("snake") => println!("Yuck! I'm throwing that snake in a fire."), - Some(inner) => println!("{}? How nice.", inner), - None => println!("No gift? Oh well."), - } -} - -// Our sheltered princess will `panic` at the sight of snakes. -// All gifts are handled implicitly using `unwrap`. -fn give_princess(gift: Option<&str>) { - // `unwrap` returns a `panic` when it receives a `None`. - let inside = gift.unwrap(); - if inside == "snake" { panic!("AAAaaaaa!!!!"); } - - println!("I love {}s!!!!!", inside); -} - -fn main() { - let food = Some("cabbage"); - let snake = Some("snake"); - let void = None; - - give_commoner(food); - give_commoner(snake); - give_commoner(void); - - let bird = Some("robin"); - let nothing = None; - - give_princess(bird); - give_princess(nothing); -} diff --git a/examples/error/panic/input.md b/examples/error/panic/input.md deleted file mode 100644 index 87c4f544da..0000000000 --- a/examples/error/panic/input.md +++ /dev/null @@ -1,5 +0,0 @@ -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. -Here, we explicitly call `panic` on our error condition: - -{panic.play} diff --git a/examples/error/panic/panic.rs b/examples/error/panic/panic.rs deleted file mode 100644 index 26d8f9f94d..0000000000 --- a/examples/error/panic/panic.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if she disapproves! - if gift == "snake" { panic!("AAAaaaaa!!!!"); } - - println!("I love {}s!!!!!", gift); -} - -fn main() { - give_princess("teddy bear"); - give_princess("snake"); -} diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md deleted file mode 100644 index 0534c043fe..0000000000 --- a/examples/error/reenter_try/input.md +++ /dev/null @@ -1,48 +0,0 @@ -Notice in the previous example that our immediate reaction to calling -`parse` is to `map` the error from a library error into our new custom -error type: - -```rust -.and_then(|s| s.parse::()) - .map_err(DoubleError::Parse) -``` - -Since this is a simple and common operation, it would be convenient if it -could be elided. Alas, because `and_then` is not sufficiently flexible, it -cannot. However, we can instead use `try!`. - -`try!` was previously explained as either `unwrap` or `return Err(err)`. -This is only mostly true. It actually means `unwrap` or -`return Err(From::from(err))`. Since `From::from` is a conversion utility -between different types, this means that if you `try!` where the error is -convertible to the return type, it will convert automatically. - -Here, we rewrite the previous example using `try!`. As a result, the -`map_err` will go away when `From::from` is implemented for our error type: - -{reenter_try.play} - -This is actually fairly clean now. Compared with the original `panic`, it -is very similar to replacing the `unwrap` calls with `try!` except that the -return types are `Result`. As a result, they must be destructured at the -top level. - -Note that you should not expect error handling of this sort to always -replace `unwrap`. This type of error handling tripled our line count and -cannot really be considered simple (even when heavily biased by the small -code size). - -Indeed, moving a 1000 line library from `unwrap` to more proper error -handling might be feasible in an additional 100 lines of code. However, the -necessary refactoring would most definitely not be trivial. - -Many libraries might get away with only implementing `Display` and -adding `From` on an as needed basis. However, more serious libraries will -eventually need to meet higher expectations of error handling implementation. - -### See also: - -[`From::from`][from] and [`try!`][try] - -[from]: https://doc.rust-lang.org/std/convert/trait.From.html -[try]: https://doc.rust-lang.org/std/macro.try!.html diff --git a/examples/error/reenter_try/reenter_try.rs b/examples/error/reenter_try/reenter_try.rs deleted file mode 100644 index da7aaeb9fd..0000000000 --- a/examples/error/reenter_try/reenter_try.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::num::ParseIntError; -use std::fmt; - -type Result = std::result::Result; - -#[derive(Debug)] -enum DoubleError { - EmptyVec, - Parse(ParseIntError), -} - -// Implement the conversion from `ParseIntError` to `DoubleError`. -// This will be automatically called by `try!` if a `ParseIntError` -// needs to be converted into a `DoubleError`. -impl From for DoubleError { - fn from(err: ParseIntError) -> DoubleError { - DoubleError::Parse(err) - } -} - -impl fmt::Display for DoubleError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - DoubleError::Parse(ref e) => e.fmt(f), - } - } -} - -// The same structure as before but rather than chain all `Results` -// and `Options` along, we `try!` to get the inner value out immediately. -fn double_first(vec: Vec<&str>) -> Result { - // Still convert to `Result` by stating how to convert `None`. - let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); - let parsed = try!(first.parse::()); - - Ok(2 * parsed) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let numbers = vec!["93", "18"]; - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(numbers)); - print(double_first(empty)); - print(double_first(strings)); -} diff --git a/examples/error/result/input.md b/examples/error/result/input.md deleted file mode 100644 index 73929635b7..0000000000 --- a/examples/error/result/input.md +++ /dev/null @@ -1,33 +0,0 @@ -[`Result`][result] is a richer version of the [`Option`][option] type that -describes possible *error* instead of possible *absence*. - -That is, `Result` could have one of two outcomes: - -* `Ok`: An element `T` was found -* `Err`: An error was found with element `E` - -By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`. - -Like `Option`, `Result` has many methods associated with it. `unwrap()`, for -example, either yields the element `T` or `panic`s. For case handling, -there are many combinators between `Result` and `Option` that overlap. - -In working with Rust, you will likely encounter methods that return the -`Result` type, such as the [`parse()`][parse] method. It might not always -be possible to parse a string into the other type, so `parse()` returns a -`Result` indicating possible failure. - -Let's see what happens when we successfully and unsuccessfully `parse()` a string: - -{result.play} - -In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` -to `panic` on. Additionally, the `panic` exits our program and provides an -unpleasant error message. - -To improve the quality of our error message, we should be more specific -about the return type and consider explicitly handling the error. - -[option]: https://doc.rust-lang.org/std/option/enum.Option.html -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/examples/error/result/result.rs b/examples/error/result/result.rs deleted file mode 100644 index baa9d3faef..0000000000 --- a/examples/error/result/result.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn double_number(number_str: &str) -> i32 { - // Let's try using `unwrap()` to get the number out. Will it bite us? - 2 * number_str.parse::().unwrap() -} - -fn main() { - let twenty = double_number("10"); - println!("double is {}", twenty); - - let tt = double_number("t"); - println!("double is {}", tt); -} diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs deleted file mode 100644 index 1d4ec4a440..0000000000 --- a/examples/error/result/result_alias/alias.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::num::ParseIntError; - -// Define a generic alias for a `Result` with the error type `ParseIntError`. -type AliasedResult = Result; - -// Use the above alias to refer to our specific `Result` type. -fn double_number(number_str: &str) -> AliasedResult { - number_str.parse::().map(|n| 2 * n) -} - -// Here, the alias again allows us to save some space. -fn print(result: AliasedResult) { - match result { - Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - print(double_number("10")); - print(double_number("t")); -} diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md deleted file mode 100644 index c552ff9872..0000000000 --- a/examples/error/result/result_alias/input.md +++ /dev/null @@ -1,19 +0,0 @@ -How about when we want to reuse a specific `Result` type many times? -Recall that Rust allows us to create [aliases][typealias]. Conveniently, -we can define one for the specific `Result` in question. - -At a module level, creating aliases can be particularly helpful. Errors -found in a specific module often have the same `Err` type, so a single alias -can succinctly define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! - -Here's a quick example to show off the syntax: - -{alias.play} - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[typealias]: /cast/alias.html -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md deleted file mode 100644 index fc4a857396..0000000000 --- a/examples/error/result/result_map/input.md +++ /dev/null @@ -1,20 +0,0 @@ -Panicking in the previous example gave us an unhelpful error message. -To avoid that, we need to be more specific about the return type. There, the -regular element is of type `i32`. - -To determine the `Err` type, we look to -[`parse()`][parse], which is implemented with the [`FromStr`][from_str] trait for -[`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. - -In the example below, the straightforward `match` statement leads to code -that is overall more cumbersome. Luckily, the `map` method of `Option` is -one of many combinators also implemented for `Result`. [`enum.Result`][result] -contains a complete listing. - -{result_map.play} - -[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse -[from_str]: https://doc.rust-lang.org/std/str/trait.FromStr.html -[i32]: https://doc.rust-lang.org/std/primitive.i32.html -[parse_int_error]: https://doc.rust-lang.org/std/num/struct.ParseIntError.html -[result]: https://doc.rust-lang.org/std/result/enum.Result.html diff --git a/examples/error/result/result_map/result_map.rs b/examples/error/result/result_map/result_map.rs deleted file mode 100644 index fbf7110bd8..0000000000 --- a/examples/error/result/result_map/result_map.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::num::ParseIntError; - -// With the return type rewritten, we use pattern matching without `unwrap()`. -fn double_number(number_str: &str) -> Result { - match number_str.parse::() { - Ok(n) => Ok(2 * n), - Err(e) => Err(e), - } -} - -// As with `Option`, we can use combinators such as `map()`. -// This function is otherwise identical to the one above and reads: -// Modify n if the value is valid, otherwise pass on the error. -fn double_number_map(number_str: &str) -> Result { - number_str.parse::().map(|n| 2 * n) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - // This still presents a reasonable answer. - let twenty = double_number("10"); - print(twenty); - - // The following now provides a much more helpful error message. - let tt = double_number_map("t"); - print(tt); -} diff --git a/src/error.md b/src/error.md index face61c6e1..c19a7b267a 100644 --- a/src/error.md +++ b/src/error.md @@ -1 +1,11 @@ # Error handling + +Error handling is the process of handling the possibility of failure. For +example, failing to read a file and then continuing to use that *bad* input +would clearly be problematic. Noticing and explicitly managing those errors +saves the rest of the program from various pitfalls. + +For a more rigorous discussion of error handling, refer to the error +handling section in the [official book][book]. + +[book]: https://doc.rust-lang.org/book/error-handling.html diff --git a/src/error/boxing_errors.md b/src/error/boxing_errors.md index 578d08fc68..9c7bcd5991 100644 --- a/src/error/boxing_errors.md +++ b/src/error/boxing_errors.md @@ -1 +1,121 @@ # `Box`ing errors + +By implementing `Display` and `From` for our error type, we enabled +almost all of the `std` library error handling tools. However, we missed +something: the ability to easily `Box` our error type. + +The `std` library automatically converts any type that implements the +`Error` trait into the trait object `Box`, via `From`. To a +library user, this conveniently allows the following: + +```rust +fn foo(...) -> Result> { ... } +``` + +A user may use any variety of external libraries which each provide their own error +types. In order to define a valid `Result` type, the user has a few choices: + +* define a new wrapper error type around the library's error types +* convert the error types to `String` or another intermediate choice +* `Box` the error types into `Box` via type erasure + +"Boxing" the error type is a common choice. The drawback is that the +underlying error type is only known at runtime and not +[statically determined][dynamic_dispatch]. As mentioned above, all that +needs to be done is to implement the `Error` trait: + +```rust +trait Error: Debug + Display { + fn description(&self) -> &str; + fn cause(&self) -> Option<&Error>; +} +``` + +With this implementation, let's look at our most recent example. Note that +it is just as valid with the error type of `Box` as it was before +with `DoubleError`: + +```rust,editable +use std::error; +use std::fmt; +use std::num::ParseIntError; + +// Change the alias to `Box`. +type Result = std::result::Result>; + +#[derive(Debug)] +enum DoubleError { + EmptyVec, + Parse(ParseIntError), +} + +impl From for DoubleError { + fn from(err: ParseIntError) -> DoubleError { + DoubleError::Parse(err) + } +} + +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + DoubleError::Parse(ref e) => e.fmt(f), + } + } +} + +impl error::Error for DoubleError { + fn description(&self) -> &str { + match *self { + // A very short description of the error. Doesn't need to be the + // same as `Display`. + DoubleError::EmptyVec => "empty vectors not allowed", + // This already impls `Error`, so defer to its own implementation. + DoubleError::Parse(ref e) => e.description(), + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + // No underlying cause so return `None`. + DoubleError::EmptyVec => None, + // The cause is the underlying implementation error type. Is implicitly + // cast to the trait object `&error::Error`. This works because the + // underlying type already implements the `Error` trait. + DoubleError::Parse(ref e) => Some(e), + } + } +} + +fn double_first(vec: Vec<&str>) -> Result { + let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); + let parsed = try!(first.parse::()); + + Ok(2 * parsed) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} +``` + +### See also: + +[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] + +[dynamic_dispatch]: https://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch +[error]: https://doc.rust-lang.org/std/error/trait.Error.html diff --git a/src/error/define_error_type.md b/src/error/define_error_type.md index ac01ddf865..83eba5a8b8 100644 --- a/src/error/define_error_type.md +++ b/src/error/define_error_type.md @@ -1 +1,87 @@ # Defining an error type + +Rust allows us to define our own error types. In general, a "good" error type: + +* Represents different errors with the same type +* Presents nice error messages to the user +* Is easy to compare with other types + - Good: `Err(EmptyVec)` + - Bad: `Err("Please use a vector with at least one element".to_owned())` +* Can hold information about the error + - Good: `Err(BadChar(c, position))` + - Bad: `Err("+ cannot be used here".to_owned())` + +Note that a `String` (which we've been using up to this point) fulfills the +first two criteria, but not the last two. This makes `String` errors verbose +to create and difficult to react to. It should not be necessary to pollute +logic heavy code with `String` formatting simply to display nicely. + +```rust,editable +use std::num::ParseIntError; +use std::fmt; + +type Result = std::result::Result; + +#[derive(Debug)] +// Define our error types. These may be customized for our error handling cases. +// Now we will be able to write our own errors, defer to an underlying error +// implementation, or do something in between. +enum DoubleError { + // We don't require any extra info to detail this error. + EmptyVec, + // We will defer to the parse error implementation for their error. + // Supplying extra info requires adding more data to the type. + Parse(ParseIntError), +} + +// Generation of an error is completely separate from how it is displayed. +// There's no need to be concerned about cluttering complex logic with the display style. +// +// Note that we don't store any extra info about the errors. This means we can't state +// which string failed to parse without modifying our types to carry that information. +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + // This is a wrapper, so defer to the underlying types' implementation of `fmt`. + DoubleError::Parse(ref e) => e.fmt(f), + } + } +} + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Change the error to our new type. + .ok_or(DoubleError::EmptyVec) + .and_then(|s| s.parse::() + // Update to the new error type here also. + .map_err(DoubleError::Parse) + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} +``` + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html +[inplace]: /error/option_with_result/result_string_errors.html diff --git a/src/error/multiple_error_types.md b/src/error/multiple_error_types.md index 9de84cfa32..a25bdfacc4 100644 --- a/src/error/multiple_error_types.md +++ b/src/error/multiple_error_types.md @@ -1 +1,80 @@ # Multiple error types + +The previous examples have always been very convenient; `Result`s interact +with other `Result`s and `Option`s interact with other `Option`s. + +Sometimes an `Option` needs to interact with a `Result`, or a +`Result` needs to interact with a `Result`. In those +cases, we want to manage our different error types in a way that makes them +composable and easy to interact with. + +In the following code, two instances of `unwrap` generate different error +types. `Vec::first` returns an `Option`, while `parse::` returns a +`Result`: + +```rust +fn double_first(vec: Vec<&str>) -> i32 { + let first = vec.first().unwrap(); // Generate error 1 + 2 * first.parse::().unwrap() // Generate error 2 +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {}", double_first(empty)); + // Error 1: the input vector is empty + + println!("The first doubled is {}", double_first(strings)); + // Error 2: the element doesn't parse to a number +} +``` + +Using our knowledge of combinators, we can rewrite the above to explicitly +handle errors. Since two different types of errors can occur, we need to +convert them to a common type such as a `String`. + +To do so, we convert both the `Option` and `Result` into `Result`s, and +then map their errors to the same type: + +```rust,editable +// Use `String` as our error type +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + .ok_or("Please use a vector with at least one element.".to_owned()) + .and_then(|s| s.parse::() + // Map any errors that `parse` yields to `String`. + .map_err(|e| e.to_string()) + // `Result` is the new return type, + // and we can now double the number inside. + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(empty)); + print(double_first(strings)); +} +``` + +In the next section, we'll see an alternate method of explicitly handling these errors. + +### See Also: + +[`Option::ok_or`][okor], [`Result::map_err`][maperr] + +[okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or +[maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err diff --git a/src/error/multiple_error_types/early_returns.md b/src/error/multiple_error_types/early_returns.md index c2684b0926..6030246e2c 100644 --- a/src/error/multiple_error_types/early_returns.md +++ b/src/error/multiple_error_types/early_returns.md @@ -1 +1,52 @@ # Early returns + +In the previous example, we explicitly handled the errors using combinators. +Another way to deal with this case analysis is to use a combination of +`match` statements and *early returns*. + +That is, we can simply stop executing the function and return the error if +one occurs. For some, this form of code can be easier to both read and +write. Consider this version of the previous example, rewritten using early returns: + +```rust,editable +// Use `String` as our error type +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + // Convert the `Option` to a `Result` if there is a value. + // Otherwise, provide an `Err` containing this `String`. + let first = match vec.first() { + Some(first) => first, + None => return Err("Please use a vector with at least one element.".to_owned()) + }; + + // Double the number inside if `parse` works fine. + // Otherwise, map any errors that `parse` yields to `String`. + match first.parse::() { + Ok(i) => Ok(2 * i), + Err(e) => Err(e.to_string()), + } +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(empty)); + print(double_first(strings)); +} +``` + +At this point, we've learned to explicitly handle errors using combinators +and early returns. While we generally want to avoid panicking, explicitly +handling all of our errors is cumbersome. + +In the next section, we'll introduce `try!` for the cases where we simply +need to `unwrap` without possibly inducing `panic`. diff --git a/src/error/multiple_error_types/enter_try.md b/src/error/multiple_error_types/enter_try.md index 5feaeda6dc..666f14d62f 100644 --- a/src/error/multiple_error_types/enter_try.md +++ b/src/error/multiple_error_types/enter_try.md @@ -1 +1,58 @@ # Introducing `try!` + +Sometimes we just want the simplicity of `unwrap` without the possibility of +a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when +what we really wanted was to get the variable *out*. This is exactly the purpose of `try!`. + +Upon finding an `Err`, there are two valid actions to take: + +1. `panic!` which we already decided to try to avoid if possible +2. `return` because an `Err` means it cannot be handled + +`try!` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s +instead of `panic`s on `Err`s. Let's see how we can simplify the earlier +example that used combinators: + +```rust,editable +// Use `String` as our error type +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + let first = try!(vec.first() + .ok_or("Please use a vector with at least one element.".to_owned())); + + let value = try!(first.parse::() + .map_err(|e| e.to_string())); + + Ok(2 * value) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(empty)); + print(double_first(strings)); +} +``` + +Note that up until now, we've been using `String`s as errors. However, they +are somewhat limiting as an error type. In the next section, we'll learn how +to make more structured and informative errors by defining their types. + +[^1]: See [re-enter try!][re_enter_try] for more details. + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html +[re_enter_try]: /error/reenter_try.html diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md index 825289d4dc..f1d8ccd9a9 100644 --- a/src/error/option_unwrap.md +++ b/src/error/option_unwrap.md @@ -1 +1,65 @@ # `Option` & `unwrap` + +In the last example, we showed that we can induce program failure at will. +We told our program to `panic` if the princess received an inappropriate +gift - a snake. But what if the princess expected a gift and didn't receive +one? That case would be just as bad, so it needs to be handled! + +We *could* test this against the null string (`""`) as we do with a snake. +Since we're using Rust, let's instead have the compiler point out cases +where there's no gift. + +An `enum` called `Option` in the `std` library is used when absence is a +possibility. It manifests itself as one of two "options": + +* `Some(T)`: An element of type `T` was found +* `None`: No element was found + +These cases can either be explicitly handled via `match` or implicitly with +`unwrap`. Implicit handling will either return the inner element or `panic`. + +Note that it's possible to manually customize `panic` with [expect][expect], +but `unwrap` otherwise leaves us with a less meaningful output than explicit +handling. In the following example, explicit handling yields a more +controlled result while retaining the option to `panic` if desired. + +```rust,editable +// The commoner has seen it all, and can handle any gift well. +// All gifts are handled explicitly using `match`. +fn give_commoner(gift: Option<&str>) { + // Specify a course of action for each case. + match gift { + Some("snake") => println!("Yuck! I'm throwing that snake in a fire."), + Some(inner) => println!("{}? How nice.", inner), + None => println!("No gift? Oh well."), + } +} + +// Our sheltered princess will `panic` at the sight of snakes. +// All gifts are handled implicitly using `unwrap`. +fn give_princess(gift: Option<&str>) { + // `unwrap` returns a `panic` when it receives a `None`. + let inside = gift.unwrap(); + if inside == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", inside); +} + +fn main() { + let food = Some("cabbage"); + let snake = Some("snake"); + let void = None; + + give_commoner(food); + give_commoner(snake); + give_commoner(void); + + let bird = Some("robin"); + let nothing = None; + + give_princess(bird); + give_princess(nothing); +} +``` + +[expect]: https://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/src/error/option_unwrap/and_then.md b/src/error/option_unwrap/and_then.md index c8863fc6c6..3c927c6848 100644 --- a/src/error/option_unwrap/and_then.md +++ b/src/error/option_unwrap/and_then.md @@ -1 +1,76 @@ # Combinators: `and_then` + +`map()` was described as a chainable way to simplify `match` statements. +However, using `map()` on a function that returns an `Option` results +in the nested `Option>`. Chaining multiple calls together can +then become confusing. That's where another combinator called `and_then()`, +known in some languages as flatmap, comes in. + +`and_then()` calls its function input with the wrapped value and returns the result. If the `Option` is `None`, then it returns `None` instead. + +In the following example, `cookable_v2()` results in an `Option`. +Using `map()` instead of `and_then()` would have given an +`Option>`, which is an invalid type for `eat()`. + +```rust,editable +#![allow(dead_code)] + +#[derive(Debug)] enum Food { CordonBleu, Steak, Sushi } +#[derive(Debug)] enum Day { Monday, Tuesday, Wednesday } + +// We don't have the ingredients to make Sushi. +fn have_ingredients(food: Food) -> Option { + match food { + Food::Sushi => None, + _ => Some(food), + } +} + +// We have the recipe for everything except Cordon Bleu. +fn have_recipe(food: Food) -> Option { + match food { + Food::CordonBleu => None, + _ => Some(food), + } +} + +// To make a dish, we need both the ingredients and the recipe. +// We can represent the logic with a chain of `match`es: +fn cookable_v1(food: Food) -> Option { + match have_ingredients(food) { + None => None, + Some(food) => match have_recipe(food) { + None => None, + Some(food) => Some(food), + }, + } +} + +// This can conveniently be rewritten more compactly with `and_then()`: +fn cookable_v2(food: Food) -> Option { + have_ingredients(food).and_then(have_recipe) +} + +fn eat(food: Food, day: Day) { + match cookable_v2(food) { + Some(food) => println!("Yay! On {:?} we get to eat {:?}.", day, food), + None => println!("Oh no. We don't get to eat on {:?}?", day), + } +} + +fn main() { + let (cordon_bleu, steak, sushi) = (Food::CordonBleu, Food::Steak, Food::Sushi); + + eat(cordon_bleu, Day::Monday); + eat(steak, Day::Tuesday); + eat(sushi, Day::Wednesday); +} +``` + +### See also: + +[closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] + +[closures]: /fn/closures.html +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[and_then]: https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/src/error/option_unwrap/map.md b/src/error/option_unwrap/map.md index 4a650ffe43..b52dda8a3a 100644 --- a/src/error/option_unwrap/map.md +++ b/src/error/option_unwrap/map.md @@ -1 +1,86 @@ # Combinators: `map` + +`match` is a valid method for handling `Option`s. However, you may +eventually find heavy usage tedious, especially with operations only valid +with an input. In these cases, [combinators][combinators] can be used to +manage control flow in a modular fashion. + +`Option` has a built in method called `map()`, a combinator for the simple +mapping of `Some -> Some` and `None -> None`. Multiple `map()` calls can be +chained together for even more flexibility. + +In the following example, `process()` replaces all functions previous +to it while staying compact. + +```rust,editable +#![allow(dead_code)] + +#[derive(Debug)] enum Food { Apple, Carrot, Potato } + +#[derive(Debug)] struct Peeled(Food); +#[derive(Debug)] struct Chopped(Food); +#[derive(Debug)] struct Cooked(Food); + +// Peeling food. If there isn't any, then return `None`. +// Otherwise, return the peeled food. +fn peel(food: Option) -> Option { + match food { + Some(food) => Some(Peeled(food)), + None => None, + } +} + +// Chopping food. If there isn't any, then return `None`. +// Otherwise, return the chopped food. +fn chop(peeled: Option) -> Option { + match peeled { + Some(Peeled(food)) => Some(Chopped(food)), + None => None, + } +} + +// Cooking food. Here, we showcase `map()` instead of `match` for case handling. +fn cook(chopped: Option) -> Option { + chopped.map(|Chopped(food)| Cooked(food)) +} + +// A function to peel, chop, and cook food all in sequence. +// We chain multiple uses of `map()` to simplify the code. +fn process(food: Option) -> Option { + food.map(|f| Peeled(f)) + .map(|Peeled(f)| Chopped(f)) + .map(|Chopped(f)| Cooked(f)) +} + +// Check whether there's food or not before trying to eat it! +fn eat(food: Option) { + match food { + Some(food) => println!("Mmm. I love {:?}", food), + None => println!("Oh no! It wasn't edible."), + } +} + +fn main() { + let apple = Some(Food::Apple); + let carrot = Some(Food::Carrot); + let potato = None; + + let cooked_apple = cook(chop(peel(apple))); + let cooked_carrot = cook(chop(peel(carrot))); + // Let's try the simpler looking `process()` now. + let cooked_potato = process(potato); + + eat(cooked_apple); + eat(cooked_carrot); + eat(cooked_potato); +} +``` + +### See also: + +[closures][closures], [`Option`][option], [`Option::map()`][map] + +[combinators]: https://doc.rust-lang.org/book/glossary.html#combinators +[closures]: /fn/closures.html +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/src/error/panic.md b/src/error/panic.md index 8d1d1a5822..2a38f96351 100644 --- a/src/error/panic.md +++ b/src/error/panic.md @@ -1 +1,19 @@ # `panic` + +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Here, we explicitly call `panic` on our error condition: + +```rust,editable +fn give_princess(gift: &str) { + // Princesses hate snakes, so we need to stop if she disapproves! + if gift == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", gift); +} + +fn main() { + give_princess("teddy bear"); + give_princess("snake"); +} +``` \ No newline at end of file diff --git a/src/error/reenter_try.md b/src/error/reenter_try.md index 8a7f9cef8c..c9151a511e 100644 --- a/src/error/reenter_try.md +++ b/src/error/reenter_try.md @@ -1 +1,107 @@ # Other uses of `try!` + +Notice in the previous example that our immediate reaction to calling +`parse` is to `map` the error from a library error into our new custom +error type: + +```rust +.and_then(|s| s.parse::()) + .map_err(DoubleError::Parse) +``` + +Since this is a simple and common operation, it would be convenient if it +could be elided. Alas, because `and_then` is not sufficiently flexible, it +cannot. However, we can instead use `try!`. + +`try!` was previously explained as either `unwrap` or `return Err(err)`. +This is only mostly true. It actually means `unwrap` or +`return Err(From::from(err))`. Since `From::from` is a conversion utility +between different types, this means that if you `try!` where the error is +convertible to the return type, it will convert automatically. + +Here, we rewrite the previous example using `try!`. As a result, the +`map_err` will go away when `From::from` is implemented for our error type: + +```rust,editable +use std::num::ParseIntError; +use std::fmt; + +type Result = std::result::Result; + +#[derive(Debug)] +enum DoubleError { + EmptyVec, + Parse(ParseIntError), +} + +// Implement the conversion from `ParseIntError` to `DoubleError`. +// This will be automatically called by `try!` if a `ParseIntError` +// needs to be converted into a `DoubleError`. +impl From for DoubleError { + fn from(err: ParseIntError) -> DoubleError { + DoubleError::Parse(err) + } +} + +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + DoubleError::Parse(ref e) => e.fmt(f), + } + } +} + +// The same structure as before but rather than chain all `Results` +// and `Options` along, we `try!` to get the inner value out immediately. +fn double_first(vec: Vec<&str>) -> Result { + // Still convert to `Result` by stating how to convert `None`. + let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); + let parsed = try!(first.parse::()); + + Ok(2 * parsed) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} +``` + +This is actually fairly clean now. Compared with the original `panic`, it +is very similar to replacing the `unwrap` calls with `try!` except that the +return types are `Result`. As a result, they must be destructured at the +top level. + +Note that you should not expect error handling of this sort to always +replace `unwrap`. This type of error handling tripled our line count and +cannot really be considered simple (even when heavily biased by the small +code size). + +Indeed, moving a 1000 line library from `unwrap` to more proper error +handling might be feasible in an additional 100 lines of code. However, the +necessary refactoring would most definitely not be trivial. + +Many libraries might get away with only implementing `Display` and +adding `From` on an as needed basis. However, more serious libraries will +eventually need to meet higher expectations of error handling implementation. + +### See also: + +[`From::from`][from] and [`try!`][try] + +[from]: https://doc.rust-lang.org/std/convert/trait.From.html +[try]: https://doc.rust-lang.org/std/macro.try!.html diff --git a/src/error/result.md b/src/error/result.md index 288cf33ef4..6e1b504f73 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -1 +1,48 @@ # `Result` + +[`Result`][result] is a richer version of the [`Option`][option] type that +describes possible *error* instead of possible *absence*. + +That is, `Result` could have one of two outcomes: + +* `Ok`: An element `T` was found +* `Err`: An error was found with element `E` + +By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`. + +Like `Option`, `Result` has many methods associated with it. `unwrap()`, for +example, either yields the element `T` or `panic`s. For case handling, +there are many combinators between `Result` and `Option` that overlap. + +In working with Rust, you will likely encounter methods that return the +`Result` type, such as the [`parse()`][parse] method. It might not always +be possible to parse a string into the other type, so `parse()` returns a +`Result` indicating possible failure. + +Let's see what happens when we successfully and unsuccessfully `parse()` a string: + +```rust,editable +fn double_number(number_str: &str) -> i32 { + // Let's try using `unwrap()` to get the number out. Will it bite us? + 2 * number_str.parse::().unwrap() +} + +fn main() { + let twenty = double_number("10"); + println!("double is {}", twenty); + + let tt = double_number("t"); + println!("double is {}", tt); +} +``` + +In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` +to `panic` on. Additionally, the `panic` exits our program and provides an +unpleasant error message. + +To improve the quality of our error message, we should be more specific +about the return type and consider explicitly handling the error. + +[option]: https://doc.rust-lang.org/std/option/enum.Option.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md index 7dc3bbd7c7..2727ca0c85 100644 --- a/src/error/result/result_alias.md +++ b/src/error/result/result_alias.md @@ -1 +1,44 @@ # aliases for `Result` + +How about when we want to reuse a specific `Result` type many times? +Recall that Rust allows us to create [aliases][typealias]. Conveniently, +we can define one for the specific `Result` in question. + +At a module level, creating aliases can be particularly helpful. Errors +found in a specific module often have the same `Err` type, so a single alias +can succinctly define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! + +Here's a quick example to show off the syntax: + +```rust,editable +use std::num::ParseIntError; + +// Define a generic alias for a `Result` with the error type `ParseIntError`. +type AliasedResult = Result; + +// Use the above alias to refer to our specific `Result` type. +fn double_number(number_str: &str) -> AliasedResult { + number_str.parse::().map(|n| 2 * n) +} + +// Here, the alias again allows us to save some space. +fn print(result: AliasedResult) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + print(double_number("10")); + print(double_number("t")); +} +``` + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[typealias]: /cast/alias.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/src/error/result/result_map.md b/src/error/result/result_map.md index a64dc9bcd3..3d21543d83 100644 --- a/src/error/result/result_map.md +++ b/src/error/result/result_map.md @@ -1 +1,56 @@ # `map` for `Result` + +Panicking in the previous example gave us an unhelpful error message. +To avoid that, we need to be more specific about the return type. There, the +regular element is of type `i32`. + +To determine the `Err` type, we look to +[`parse()`][parse], which is implemented with the [`FromStr`][from_str] trait for +[`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. + +In the example below, the straightforward `match` statement leads to code +that is overall more cumbersome. Luckily, the `map` method of `Option` is +one of many combinators also implemented for `Result`. [`enum.Result`][result] +contains a complete listing. + +```rust,editable +use std::num::ParseIntError; + +// With the return type rewritten, we use pattern matching without `unwrap()`. +fn double_number(number_str: &str) -> Result { + match number_str.parse::() { + Ok(n) => Ok(2 * n), + Err(e) => Err(e), + } +} + +// As with `Option`, we can use combinators such as `map()`. +// This function is otherwise identical to the one above and reads: +// Modify n if the value is valid, otherwise pass on the error. +fn double_number_map(number_str: &str) -> Result { + number_str.parse::().map(|n| 2 * n) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + // This still presents a reasonable answer. + let twenty = double_number("10"); + print(twenty); + + // The following now provides a much more helpful error message. + let tt = double_number_map("t"); + print(tt); +} +``` + +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse +[from_str]: https://doc.rust-lang.org/std/str/trait.FromStr.html +[i32]: https://doc.rust-lang.org/std/primitive.i32.html +[parse_int_error]: https://doc.rust-lang.org/std/num/struct.ParseIntError.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html From e4af7820ed4038c425900aec8a8ae61a3fa8f631 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 16:59:30 -0400 Subject: [PATCH 0639/1122] macros chapter --- examples/macros/designators/designators.rs | 42 ------------ examples/macros/designators/input.md | 16 ----- examples/macros/dry/dry.rs | 58 ----------------- examples/macros/dry/input.md | 15 ----- examples/macros/input.md | 8 --- examples/macros/overload/input.md | 4 -- examples/macros/overload/overload.rs | 24 ------- examples/macros/repeat/input.md | 9 --- examples/macros/repeat/repeat.rs | 16 ----- examples/macros/simple.rs | 13 ---- src/macros.md | 23 +++++++ src/macros/designators.md | 60 ++++++++++++++++++ src/macros/dry.md | 74 ++++++++++++++++++++++ src/macros/overload.md | 30 +++++++++ src/macros/repeat.md | 27 ++++++++ 15 files changed, 214 insertions(+), 205 deletions(-) delete mode 100644 examples/macros/designators/designators.rs delete mode 100644 examples/macros/designators/input.md delete mode 100644 examples/macros/dry/dry.rs delete mode 100644 examples/macros/dry/input.md delete mode 100644 examples/macros/input.md delete mode 100644 examples/macros/overload/input.md delete mode 100644 examples/macros/overload/overload.rs delete mode 100644 examples/macros/repeat/input.md delete mode 100644 examples/macros/repeat/repeat.rs delete mode 100644 examples/macros/simple.rs diff --git a/examples/macros/designators/designators.rs b/examples/macros/designators/designators.rs deleted file mode 100644 index d85f9c7348..0000000000 --- a/examples/macros/designators/designators.rs +++ /dev/null @@ -1,42 +0,0 @@ -macro_rules! create_function { - // This macro takes an argument of designator `ident` and - // creates a function named `$func_name`. - // The `ident` designator is used for variable/function names. - ($func_name:ident) => ( - fn $func_name() { - // The `stringify!` macro converts an `ident` into a string. - println!("You called {:?}()", - stringify!($func_name)) - } - ) -} - -// Create functions named `foo` and `bar` with the above macro. -create_function!(foo); -create_function!(bar); - -macro_rules! print_result { - // This macro takes an expression of type `expr` and prints - // it as a string along with its result. - // The `expr` designator is used for expressions. - ($expression:expr) => ( - // `stringify!` will convert the expression *as it is* into a string. - println!("{:?} = {:?}", - stringify!($expression), - $expression) - ) -} - -fn main() { - foo(); - bar(); - - print_result!(1u32 + 1); - - // Recall that blocks are expressions too! - print_result!({ - let x = 1u32; - - x * x + 2 * x - 1 - }); -} diff --git a/examples/macros/designators/input.md b/examples/macros/designators/input.md deleted file mode 100644 index 9e64a10745..0000000000 --- a/examples/macros/designators/input.md +++ /dev/null @@ -1,16 +0,0 @@ -The arguments of a macro are prefixed by a dollar sign `$` and type annotated -with a *designator*: - -{designators.play} - -This is a list of all the designators: - -* `block` -* `expr` is used for expressions -* `ident` is used for variable/function names -* `item` -* `pat` (*pattern*) -* `path` -* `stmt` (*statement*) -* `tt` (*token tree*) -* `ty` (*type*) diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs deleted file mode 100644 index 111bb4e237..0000000000 --- a/examples/macros/dry/dry.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::ops::{Add, Mul, Sub}; - -macro_rules! assert_equal_len { - // The `tt` (token tree) designator is used for - // operators and tokens. - ($a:ident, $b: ident, $func:ident, $op:tt) => ( - assert!($a.len() == $b.len(), - "{:?}: dimension mismatch: {:?} {:?} {:?}", - stringify!($func), - ($a.len(),), - stringify!($op), - ($b.len(),)); - ) -} - -macro_rules! op { - ($func:ident, $bound:ident, $op:tt, $method:ident) => ( - fn $func + Copy>(xs: &mut Vec, ys: &Vec) { - assert_equal_len!(xs, ys, $func, $op); - - for (x, y) in xs.iter_mut().zip(ys.iter()) { - *x = $bound::$method(*x, *y); - // *x = x.$method(*y); - } - } - ) -} - -// Implement `add_assign`, `mul_assign`, and `sub_assign` functions. -op!(add_assign, Add, +=, add); -op!(mul_assign, Mul, *=, mul); -op!(sub_assign, Sub, -=, sub); - -mod test { - use std::iter; - macro_rules! test { - ($func: ident, $x:expr, $y:expr, $z:expr) => { - #[test] - fn $func() { - for size in 0usize..10 { - let mut x: Vec<_> = iter::repeat($x).take(size).collect(); - let y: Vec<_> = iter::repeat($y).take(size).collect(); - let z: Vec<_> = iter::repeat($z).take(size).collect(); - - super::$func(&mut x, &y); - - assert_eq!(x, z); - } - } - } - } - - // Test `add_assign`, `mul_assign` and `sub_assign` - test!(add_assign, 1u32, 2u32, 3u32); - test!(mul_assign, 2u32, 3u32, 6u32); - test!(sub_assign, 3u32, 2u32, 1u32); -} - diff --git a/examples/macros/dry/input.md b/examples/macros/dry/input.md deleted file mode 100644 index 32391a5571..0000000000 --- a/examples/macros/dry/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Macros allow writing DRY code by factoring out the common parts of functions -and/or test suites. Here is an example that implements and tests the `+=`, `*=` -and `-=` operators on `Vec`: - -{dry.rs} - -``` -$ rustc --test dry.rs && ./dry -running 3 tests -test test::mul_assign ... ok -test test::add_assign ... ok -test test::sub_assign ... ok - -test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured -``` diff --git a/examples/macros/input.md b/examples/macros/input.md deleted file mode 100644 index a3eb6c12d2..0000000000 --- a/examples/macros/input.md +++ /dev/null @@ -1,8 +0,0 @@ -Rust provides a powerful macro system that allows metaprogramming. As you've -seen in previous chapters, macros look like functions, except that their name -ends with a bang `!`, but instead of generating a function call, macros are -expanded into source code that gets compiled with the rest of the program. - -Macros are created using the `macro_rules!` macro. - -{simple.play} diff --git a/examples/macros/overload/input.md b/examples/macros/overload/input.md deleted file mode 100644 index 2d166ce32a..0000000000 --- a/examples/macros/overload/input.md +++ /dev/null @@ -1,4 +0,0 @@ -Macros can be overloaded to accept different combinations of arguments. -In that regard, `macro_rules!` can work similarly to a match block: - -{overload.play} diff --git a/examples/macros/overload/overload.rs b/examples/macros/overload/overload.rs deleted file mode 100644 index 389df55536..0000000000 --- a/examples/macros/overload/overload.rs +++ /dev/null @@ -1,24 +0,0 @@ -// `test!` will compare `$left` and `$right` -// in different ways depending on how you invoke it: -macro_rules! test { - // Arguments don't need to be separated by a comma. - // Any template can be used! - ($left:expr; and $right:expr) => ( - println!("{:?} and {:?} is {:?}", - stringify!($left), - stringify!($right), - $left && $right) - ); - // ^ each arm must end with a semicolon. - ($left:expr; or $right:expr) => ( - println!("{:?} or {:?} is {:?}", - stringify!($left), - stringify!($right), - $left || $right) - ); -} - -fn main() { - test!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); - test!(true; or false); -} diff --git a/examples/macros/repeat/input.md b/examples/macros/repeat/input.md deleted file mode 100644 index 5c5483e6a1..0000000000 --- a/examples/macros/repeat/input.md +++ /dev/null @@ -1,9 +0,0 @@ -Macros can use `+` in the argument list to indicate that an argument may -repeat at least once, or `*`, to indicate that the argument may repeat zero or -more times. - -In the following example, surrounding the matcher with `$(...),+` will -match one or more expression, separated by commas. -Also note that the semicolon is optional on the last case. - -{repeat.play} diff --git a/examples/macros/repeat/repeat.rs b/examples/macros/repeat/repeat.rs deleted file mode 100644 index e25aad8d29..0000000000 --- a/examples/macros/repeat/repeat.rs +++ /dev/null @@ -1,16 +0,0 @@ -// `min!` will calculate the minimum of any number of arguments. -macro_rules! find_min { - // Base case: - ($x:expr) => ($x); - // `$x` followed by at least one `$y,` - ($x:expr, $($y:expr),+) => ( - // Call `find_min!` on the tail `$y` - std::cmp::min($x, find_min!($($y),+)) - ) -} - -fn main() { - println!("{}", find_min!(1u32)); - println!("{}", find_min!(1u32 + 2 , 2u32)); - println!("{}", find_min!(5u32, 2u32 * 3, 4u32)); -} diff --git a/examples/macros/simple.rs b/examples/macros/simple.rs deleted file mode 100644 index 4268b6fef4..0000000000 --- a/examples/macros/simple.rs +++ /dev/null @@ -1,13 +0,0 @@ -// This is a simple macro named `say_hello`. -macro_rules! say_hello { - // `()` indicates that the macro takes no argument. - () => ( - // The macro will expand into the contents of this block. - println!("Hello!"); - ) -} - -fn main() { - // This call will expand into `println!("Hello");` - say_hello!() -} diff --git a/src/macros.md b/src/macros.md index 695221abf8..9f5a7c4276 100644 --- a/src/macros.md +++ b/src/macros.md @@ -1 +1,24 @@ # macro_rules! + +Rust provides a powerful macro system that allows metaprogramming. As you've +seen in previous chapters, macros look like functions, except that their name +ends with a bang `!`, but instead of generating a function call, macros are +expanded into source code that gets compiled with the rest of the program. + +Macros are created using the `macro_rules!` macro. + +```rust,editable +// This is a simple macro named `say_hello`. +macro_rules! say_hello { + // `()` indicates that the macro takes no argument. + () => ( + // The macro will expand into the contents of this block. + println!("Hello!"); + ) +} + +fn main() { + // This call will expand into `println!("Hello");` + say_hello!() +} +``` \ No newline at end of file diff --git a/src/macros/designators.md b/src/macros/designators.md index b6a41ad331..50d5e42481 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -1 +1,61 @@ # Designators + +The arguments of a macro are prefixed by a dollar sign `$` and type annotated +with a *designator*: + +```rust,editable +macro_rules! create_function { + // This macro takes an argument of designator `ident` and + // creates a function named `$func_name`. + // The `ident` designator is used for variable/function names. + ($func_name:ident) => ( + fn $func_name() { + // The `stringify!` macro converts an `ident` into a string. + println!("You called {:?}()", + stringify!($func_name)) + } + ) +} + +// Create functions named `foo` and `bar` with the above macro. +create_function!(foo); +create_function!(bar); + +macro_rules! print_result { + // This macro takes an expression of type `expr` and prints + // it as a string along with its result. + // The `expr` designator is used for expressions. + ($expression:expr) => ( + // `stringify!` will convert the expression *as it is* into a string. + println!("{:?} = {:?}", + stringify!($expression), + $expression) + ) +} + +fn main() { + foo(); + bar(); + + print_result!(1u32 + 1); + + // Recall that blocks are expressions too! + print_result!({ + let x = 1u32; + + x * x + 2 * x - 1 + }); +} +``` + +This is a list of all the designators: + +* `block` +* `expr` is used for expressions +* `ident` is used for variable/function names +* `item` +* `pat` (*pattern*) +* `path` +* `stmt` (*statement*) +* `tt` (*token tree*) +* `ty` (*type*) diff --git a/src/macros/dry.md b/src/macros/dry.md index 02196ef53e..6e765e8469 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -1 +1,75 @@ # DRY (Don't Repeat Yourself) + +Macros allow writing DRY code by factoring out the common parts of functions +and/or test suites. Here is an example that implements and tests the `+=`, `*=` +and `-=` operators on `Vec`: + +```rust,editable +use std::ops::{Add, Mul, Sub}; + +macro_rules! assert_equal_len { + // The `tt` (token tree) designator is used for + // operators and tokens. + ($a:ident, $b: ident, $func:ident, $op:tt) => ( + assert!($a.len() == $b.len(), + "{:?}: dimension mismatch: {:?} {:?} {:?}", + stringify!($func), + ($a.len(),), + stringify!($op), + ($b.len(),)); + ) +} + +macro_rules! op { + ($func:ident, $bound:ident, $op:tt, $method:ident) => ( + fn $func + Copy>(xs: &mut Vec, ys: &Vec) { + assert_equal_len!(xs, ys, $func, $op); + + for (x, y) in xs.iter_mut().zip(ys.iter()) { + *x = $bound::$method(*x, *y); + // *x = x.$method(*y); + } + } + ) +} + +// Implement `add_assign`, `mul_assign`, and `sub_assign` functions. +op!(add_assign, Add, +=, add); +op!(mul_assign, Mul, *=, mul); +op!(sub_assign, Sub, -=, sub); + +mod test { + use std::iter; + macro_rules! test { + ($func: ident, $x:expr, $y:expr, $z:expr) => { + #[test] + fn $func() { + for size in 0usize..10 { + let mut x: Vec<_> = iter::repeat($x).take(size).collect(); + let y: Vec<_> = iter::repeat($y).take(size).collect(); + let z: Vec<_> = iter::repeat($z).take(size).collect(); + + super::$func(&mut x, &y); + + assert_eq!(x, z); + } + } + } + } + + // Test `add_assign`, `mul_assign` and `sub_assign` + test!(add_assign, 1u32, 2u32, 3u32); + test!(mul_assign, 2u32, 3u32, 6u32); + test!(sub_assign, 3u32, 2u32, 1u32); +} +``` + +```bash +$ rustc --test dry.rs && ./dry +running 3 tests +test test::mul_assign ... ok +test test::add_assign ... ok +test test::sub_assign ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured +``` diff --git a/src/macros/overload.md b/src/macros/overload.md index 6819d74a4b..6415e2e4dc 100644 --- a/src/macros/overload.md +++ b/src/macros/overload.md @@ -1 +1,31 @@ # Overload + +Macros can be overloaded to accept different combinations of arguments. +In that regard, `macro_rules!` can work similarly to a match block: + +```rust,editable +// `test!` will compare `$left` and `$right` +// in different ways depending on how you invoke it: +macro_rules! test { + // Arguments don't need to be separated by a comma. + // Any template can be used! + ($left:expr; and $right:expr) => ( + println!("{:?} and {:?} is {:?}", + stringify!($left), + stringify!($right), + $left && $right) + ); + // ^ each arm must end with a semicolon. + ($left:expr; or $right:expr) => ( + println!("{:?} or {:?} is {:?}", + stringify!($left), + stringify!($right), + $left || $right) + ); +} + +fn main() { + test!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); + test!(true; or false); +} +``` \ No newline at end of file diff --git a/src/macros/repeat.md b/src/macros/repeat.md index 5f50dadb6d..2b00387972 100644 --- a/src/macros/repeat.md +++ b/src/macros/repeat.md @@ -1 +1,28 @@ # Repeat + +Macros can use `+` in the argument list to indicate that an argument may +repeat at least once, or `*`, to indicate that the argument may repeat zero or +more times. + +In the following example, surrounding the matcher with `$(...),+` will +match one or more expression, separated by commas. +Also note that the semicolon is optional on the last case. + +```rust,editable +// `min!` will calculate the minimum of any number of arguments. +macro_rules! find_min { + // Base case: + ($x:expr) => ($x); + // `$x` followed by at least one `$y,` + ($x:expr, $($y:expr),+) => ( + // Call `find_min!` on the tail `$y` + std::cmp::min($x, find_min!($($y),+)) + ) +} + +fn main() { + println!("{}", find_min!(1u32)); + println!("{}", find_min!(1u32 + 2 , 2u32)); + println!("{}", find_min!(5u32, 2u32 * 3, 4u32)); +} +``` \ No newline at end of file From 5f8e537c7b0fd07785dbef533a82e728a80f46bd Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 17:28:59 -0400 Subject: [PATCH 0640/1122] remove some more unused things --- examples/structure.json | 200 ---------------------------------------- examples/todo/input.md | 4 - 2 files changed, 204 deletions(-) delete mode 100644 examples/structure.json delete mode 100644 examples/todo/input.md diff --git a/examples/structure.json b/examples/structure.json deleted file mode 100644 index f6c33737eb..0000000000 --- a/examples/structure.json +++ /dev/null @@ -1,200 +0,0 @@ -[ - { "id": "hello", "title": "Hello World", "children": [ - { "id": "comment", "title": "Comments", "children": null }, - { "id": "print", "title": "Formatted print", "children": [ - { "id": "print_debug", "title": "Debug", "children": null }, - { "id": "print_display", "title": "Display", "children": [ - { "id": "testcase_list", "title": "Testcase: List", "children": null } - ] }, - { "id": "fmt", "title": "Formatting", "children": null } - ] } - ] }, - { "id": "primitives", "title": "Primitives", "children": [ - { "id": "literals", "title": "Literals and operators", "children": null }, - { "id": "tuples", "title": "Tuples", "children": null }, - { "id": "array", "title": "Arrays and Slices", "children": null } - ] }, - { "id": "custom_types", "title": "Custom types", "children": [ - { "id": "structs", "title": "Structures", "children": null }, - { "id": "enum", "title": "Enums", "children": [ - { "id": "enum_use", "title": "use", "children": null }, - { "id": "c_like", "title": "C-like", "children": null }, - { "id": "testcase_linked_list", "title": "Testcase: linked-list", "children": null } - ] }, - { "id": "constants", "title": "constants", "children": null } - ] }, - { "id": "variable_bindings", "title": "Variable Bindings", "children": [ - { "id": "mut", "title": "Mutability", "children": null }, - { "id": "scope", "title": "Scope and shadowing", "children": null }, - { "id": "declare", "title": "Declare first", "children": null } - ] }, - { "id": "cast", "title": "Casting", "children": [ - { "id": "literals", "title": "Literals", "children": null }, - { "id": "inference", "title": "Inference", "children": null }, - { "id": "alias", "title": "Alias", "children": null } - ] }, - { "id": "expression", "title": "Expressions", "children": null }, - { "id": "flow_control", "title": "Flow Control", "children": [ - { "id": "if_else", "title": "if/else", "children": null }, - { "id": "loop", "title": "loop", "children": [ - { "id": "nested", "title": "Nesting and labels", "children": null }, - { "id": "return", "title": "Returning from loops", "children": null } - ] }, - { "id": "while", "title": "while", "children": null }, - { "id": "for", "title": "for and range", "children": null }, - { "id": "match", "title": "match", "children": [ - { "id": "destructuring", "title": "Destructuring", "children": [ - { "id": "destructure_tuple", "title": "tuples", "children": null }, - { "id": "destructure_enum", "title": "enums", "children": null }, - { "id": "destructure_pointers", "title": "pointers/ref", "children": null }, - { "id": "destructure_structures", "title": "structs", "children": null } - ] }, - { "id": "guard", "title": "Guards", "children": null }, - { "id": "binding", "title": "Binding", "children": null } - ] }, - { "id": "if_let", "title": "if let", "children": null }, - { "id": "while_let", "title": "while let", "children": null } - ] }, - { "id": "fn", "title": "Functions", "children": [ - { "id": "methods", "title": "Methods", "children": null }, - { "id": "closures", "title": "Closures", "children": [ - { "id": "capture", "title": "Capturing", "children": null }, - { "id": "input_parameters", "title": "As input parameters", "children": null }, - { "id": "anonymity", "title": "Type anonymity", "children": null }, - { "id": "input_functions", "title": "Input functions", "children": null }, - { "id": "output_parameters", "title": "As output parameters", "children": null }, - { "id": "closure_examples", "title": "Examples in `std`", "children": [ - { "id": "iter_any", "title": "Iterator::any", "children": null }, - { "id": "iter_find", "title": "Iterator::find", "children": null } - ] } - ] }, - { "id": "hof", "title": "Higher Order Functions", "children": null } - ] }, - { "id": "mod", "title": "Modules", "children": [ - { "id": "visibility", "title": "Visibility", "children": null }, - { "id": "struct_visibility", "title": "Struct visibility", "children": null }, - { "id": "use", "title": "The `use` declaration", "children": null }, - { "id": "super", "title": "`super` and `self`", "children": null }, - { "id": "split", "title": "File hierarchy", "children": null } - ] }, - { "id": "crates", "title": "Crates", "children": [ - { "id": "lib", "title": "Library", "children": null }, - { "id": "link", "title": "`extern crate`", "children": null } - ] }, - { "id": "attribute", "title": "Attributes", "children": [ - { "id": "unused", "title": "`dead_code`", "children": null }, - { "id": "crate", "title": "Crates", "children": null }, - { "id": "cfg", "title": "`cfg`", "children": [ - { "id": "custom", "title": "Custom", "children": null } - ] } - ] }, - { "id": "generics", "title": "Generics", "children": [ - { "id": "gen_fn", "title": "Functions", "children": null }, - { "id": "impl", "title": "Implementation", "children": null }, - { "id": "gen_trait", "title": "Traits", "children": null }, - { "id": "bounds", "title": "Bounds", "children": [ - { "id": "testcase_empty", "title": "Testcase: empty bounds", "children": null } - ] }, - { "id": "multi_bounds", "title": "Multiple bounds", "children": null }, - { "id": "where", "title": "Where clauses", "children": null }, - { "id": "assoc_items", "title": "Associated items", "children": [ - { "id": "the_problem", "title": "The Problem", "children": null }, - { "id": "types", "title": "Associated types", "children": null } - ] }, - { "id": "phantom", "title": "Phantom type parameters", "children": [ - { "id": "testcase_units", "title": "Testcase: unit clarification", "children": null } - ] } - ] }, - { "id": "scope", "title": "Scoping rules", "children": [ - { "id": "raii", "title": "RAII", "children": null }, - { "id": "move", "title": "Ownership and moves", "children": [ - { "id": "mut", "title": "Mutability", "children": null } - ] }, - { "id": "borrow", "title": "Borrowing", "children": [ - { "id": "mut", "title": "Mutability", "children": null }, - { "id": "freeze", "title": "Freezing", "children": null }, - { "id": "alias", "title": "Aliasing", "children": null }, - { "id": "ref", "title": "The ref pattern", "children": null } - ] }, - { "id": "lifetime", "title": "Lifetimes", "children": [ - { "id": "explicit", "title": "Explicit annotation", "children": null }, - { "id": "fn", "title": "Functions", "children": null }, - { "id": "methods", "title": "Methods", "children": null }, - { "id": "struct", "title": "Structs", "children": null }, - { "id": "lifetime_bounds", "title": "Bounds", "children": null }, - { "id": "lifetime_coercion", "title": "Coercion", "children": null }, - { "id": "static_lifetime", "title": "static", "children": null }, - { "id": "elision", "title": "elision", "children": null } - ] } - ] }, - { "id": "trait", "title": "Traits", "children": [ - { "id": "derive", "title": "Derive", "children": null }, - { "id": "ops", "title": "Operator Overloading", "children": null }, - { "id": "drop", "title": "Drop", "children": null }, - { "id": "iter", "title": "Iterators", "children": null }, - { "id": "clone", "title": "Clone", "children": null } - ] }, - { "id": "macros", "title": "macro_rules!", "children": [ - { "id": "designators", "title": "Designators", "children": null }, - { "id": "overload", "title": "Overload", "children": null }, - { "id": "repeat", "title": "Repeat", "children": null }, - { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } - ] }, - { "id": "error", "title": "Error handling", "children": [ - { "id": "panic", "title": "`panic`", "children": null }, - { "id": "option_unwrap", "title": "`Option` & `unwrap`", "children": [ - { "id": "map", "title": "Combinators: `map`", "children": null }, - { "id": "and_then", "title": "Combinators: `and_then`", "children": null } - ] }, - { "id": "result", "title": "`Result`", "children": [ - { "id": "result_map", "title": "`map` for `Result`", "children": null }, - { "id": "result_alias", "title": "aliases for `Result`", "children": null } - ] }, - { "id": "multiple_error_types", "title": "Multiple error types", "children": [ - { "id": "early_returns", "title": "Early returns", "children": null }, - { "id": "enter_try", "title": "Introducing `try!`", "children": null } - ] }, - { "id": "define_error_type", "title": "Defining an error type", "children": null }, - { "id": "reenter_try", "title": "Other uses of `try!`", "children": null }, - { "id": "boxing_errors", "title": "`Box`ing errors", "children": null } - ] }, - { "id": "std", "title": "Std library types", "children": [ - { "id": "box", "title": "Box, stack and heap", "children": null }, - { "id": "vec", "title": "Vectors", "children": null }, - { "id": "str", "title": "Strings", "children": null }, - { "id": "option", "title": "`Option`", "children": null }, - { "id": "result", "title": "`Result`", "children": [ - { "id": "try", "title": "`try!`", "children": null } - ] }, - { "id": "panic", "title": "`panic!`", "children": null }, - { "id": "hash", "title": "HashMap", "children": [ - { "id": "alt_key_types", "title": "Alternate/custom key types", "children": null}, - { "id": "hashset", "title": "HashSet", "children": null } - ] } - ] }, - { "id": "std_misc", "title": "Std misc", "children": [ - { "id": "threads", "title": "Threads", "children": [ - { "id": "testcase_mapreduce", "title": "Testcase: map-reduce", "children": null} - ] }, - { "id": "channels", "title": "Channels", "children": null }, - { "id": "path", "title": "Path", "children": null }, - { "id": "file", "title": "File I/O", "children": [ - { "id": "open", "title": "`open`", "children": null }, - { "id": "create", "title": "`create`", "children": null } - ] }, - { "id": "process", "title": "Child processes", "children": [ - { "id": "pipe", "title": "Pipes", "children": null }, - { "id": "wait", "title": "Wait", "children": null } - ] }, - { "id": "fs", "title": "Filesystem Operations", "children": null }, - { "id": "arg", "title": "Program arguments", "children": [ - { "id": "matching", "title": "Argument parsing", "children": null } - ] }, - { "id": "ffi", "title": "Foreign Function Interface", "children": null } - ] }, - { "id": "meta", "title": "Meta", "children": [ - { "id": "doc", "title": "Documentation", "children": null }, - { "id": "test", "title": "Testing", "children": null } - ] }, - { "id": "unsafe", "title": "Unsafe operations", "children": null } -] diff --git a/examples/todo/input.md b/examples/todo/input.md deleted file mode 100644 index 8b254a0fc1..0000000000 --- a/examples/todo/input.md +++ /dev/null @@ -1,4 +0,0 @@ -If you would like to see a chapter about some concept or library, please drop a -comment in [issue #1][issue-1] - -[issue-1]: https://github.com/rust-lang/rust-by-example/issues/1 From 2147fc6f22322617e05e0675499cb1c11c32a533 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 17:30:21 -0400 Subject: [PATCH 0641/1122] Set up the README --- examples/README.md | 17 ----------------- src/index.md | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 18 deletions(-) delete mode 100644 examples/README.md diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index b295932fb5..0000000000 --- a/examples/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Rust by Example - -[Rust][rust] is a modern systems programming language focusing on safety, speed, -and concurrency. It accomplishes these goals by being memory safe without using -garbage collection. - -Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust -concepts and standard libraries. To get even more out of these examples, don't forget -to [install Rust locally][install] and check out the [official docs][std]. -Additionally for the curious, you can also [check out the source code for this site][home]. - -Now let's begin! - -[rust]: https://www.rust-lang.org/ -[install]: https://www.rust-lang.org/install.html -[std]: https://doc.rust-lang.org/std/ -[home]: https://github.com/rust-lang/rust-by-example diff --git a/src/index.md b/src/index.md index e10b99d013..b295932fb5 100644 --- a/src/index.md +++ b/src/index.md @@ -1 +1,17 @@ -# Introduction +# Rust by Example + +[Rust][rust] is a modern systems programming language focusing on safety, speed, +and concurrency. It accomplishes these goals by being memory safe without using +garbage collection. + +Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust +concepts and standard libraries. To get even more out of these examples, don't forget +to [install Rust locally][install] and check out the [official docs][std]. +Additionally for the curious, you can also [check out the source code for this site][home]. + +Now let's begin! + +[rust]: https://www.rust-lang.org/ +[install]: https://www.rust-lang.org/install.html +[std]: https://doc.rust-lang.org/std/ +[home]: https://github.com/rust-lang/rust-by-example From d28850ceef2402a2d68ce5e309e90494d7d73936 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 17:43:40 -0400 Subject: [PATCH 0642/1122] Flow control --- examples/flow_control/for/for.rs | 14 ---- examples/flow_control/for/input.md | 14 ---- examples/flow_control/if_else/if_else.rs | 28 -------- examples/flow_control/if_else/input.md | 6 -- examples/flow_control/if_let/if_let.rs | 34 ---------- examples/flow_control/if_let/input.md | 31 --------- examples/flow_control/input.md | 2 - examples/flow_control/loop/input.md | 7 -- examples/flow_control/loop/loop.rs | 26 ------- examples/flow_control/loop/nested/input.md | 5 -- examples/flow_control/loop/nested/nested.rs | 21 ------ examples/flow_control/loop/return/input.md | 6 -- examples/flow_control/loop/return/return.rs | 13 ---- .../flow_control/match/binding/binding.rs | 19 ------ examples/flow_control/match/binding/input.md | 10 --- .../destructuring/destructure_enum/enum.rs | 40 ----------- .../destructuring/destructure_enum/input.md | 11 --- .../destructure_pointers/input.md | 8 --- .../destructure_pointers/pointers.rs | 50 -------------- .../destructure_references/input.md | 10 --- .../destructure_references/ref.rs | 23 ------- .../destructure_structures/input.md | 7 -- .../destructure_structures/struct.rs | 22 ------ .../destructuring/destructure_tuple/input.md | 7 -- .../destructuring/destructure_tuple/tuples.rs | 14 ---- .../flow_control/match/destructuring/input.md | 1 - examples/flow_control/match/guard/guard.rs | 13 ---- examples/flow_control/match/guard/input.md | 7 -- examples/flow_control/match/input.md | 4 -- examples/flow_control/match/match.rs | 27 -------- examples/flow_control/while/input.md | 7 -- examples/flow_control/while/while.rs | 20 ------ examples/flow_control/while_let/input.md | 39 ----------- examples/flow_control/while_let/while_let.rs | 20 ------ src/flow_control.md | 3 + src/flow_control/for.md | 30 +++++++++ src/flow_control/if_else.md | 36 ++++++++++ src/flow_control/if_let.md | 67 +++++++++++++++++++ src/flow_control/loop.md | 35 ++++++++++ src/flow_control/loop/nested.md | 28 ++++++++ src/flow_control/loop/return.md | 21 ++++++ src/flow_control/match.md | 33 +++++++++ src/flow_control/match/binding.md | 31 +++++++++ src/flow_control/match/destructuring.md | 2 + .../match/destructuring/destructure_enum.md | 53 +++++++++++++++ .../destructuring/destructure_pointers.md | 60 +++++++++++++++++ .../destructuring/destructure_structures.md | 31 +++++++++ .../match/destructuring/destructure_tuple.md | 23 +++++++ src/flow_control/match/guard.md | 22 ++++++ src/flow_control/while.md | 29 ++++++++ src/flow_control/while_let.md | 61 +++++++++++++++++ 51 files changed, 565 insertions(+), 566 deletions(-) delete mode 100644 examples/flow_control/for/for.rs delete mode 100644 examples/flow_control/for/input.md delete mode 100644 examples/flow_control/if_else/if_else.rs delete mode 100644 examples/flow_control/if_else/input.md delete mode 100644 examples/flow_control/if_let/if_let.rs delete mode 100644 examples/flow_control/if_let/input.md delete mode 100644 examples/flow_control/input.md delete mode 100644 examples/flow_control/loop/input.md delete mode 100644 examples/flow_control/loop/loop.rs delete mode 100644 examples/flow_control/loop/nested/input.md delete mode 100644 examples/flow_control/loop/nested/nested.rs delete mode 100644 examples/flow_control/loop/return/input.md delete mode 100644 examples/flow_control/loop/return/return.rs delete mode 100644 examples/flow_control/match/binding/binding.rs delete mode 100644 examples/flow_control/match/binding/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_enum/enum.rs delete mode 100644 examples/flow_control/match/destructuring/destructure_enum/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_pointers/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_pointers/pointers.rs delete mode 100644 examples/flow_control/match/destructuring/destructure_references/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_references/ref.rs delete mode 100644 examples/flow_control/match/destructuring/destructure_structures/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_structures/struct.rs delete mode 100644 examples/flow_control/match/destructuring/destructure_tuple/input.md delete mode 100644 examples/flow_control/match/destructuring/destructure_tuple/tuples.rs delete mode 100644 examples/flow_control/match/destructuring/input.md delete mode 100644 examples/flow_control/match/guard/guard.rs delete mode 100644 examples/flow_control/match/guard/input.md delete mode 100644 examples/flow_control/match/input.md delete mode 100644 examples/flow_control/match/match.rs delete mode 100644 examples/flow_control/while/input.md delete mode 100644 examples/flow_control/while/while.rs delete mode 100644 examples/flow_control/while_let/input.md delete mode 100644 examples/flow_control/while_let/while_let.rs diff --git a/examples/flow_control/for/for.rs b/examples/flow_control/for/for.rs deleted file mode 100644 index 3a91b0c9a9..0000000000 --- a/examples/flow_control/for/for.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - // `n` will take the values: 1, 2, ..., 100 in each iteration - for n in 1..101 { - if n % 15 == 0 { - println!("fizzbuzz"); - } else if n % 3 == 0 { - println!("fizz"); - } else if n % 5 == 0 { - println!("buzz"); - } else { - println!("{}", n); - } - } -} diff --git a/examples/flow_control/for/input.md b/examples/flow_control/for/input.md deleted file mode 100644 index 1688afe029..0000000000 --- a/examples/flow_control/for/input.md +++ /dev/null @@ -1,14 +0,0 @@ -The `for in` construct can be used to iterate through an `Iterator`. -One of the easiest ways to create an iterator is to use the range -notation `a..b`. This yields values from `a` (inclusive) to `b` -(exclusive) in steps of one. - -Let's write FizzBuzz using `for` instead of `while`. - -{for.play} - -###See also - -[Iterator][iter] - -[iter]: /trait/iter.html \ No newline at end of file diff --git a/examples/flow_control/if_else/if_else.rs b/examples/flow_control/if_else/if_else.rs deleted file mode 100644 index 516d4a9745..0000000000 --- a/examples/flow_control/if_else/if_else.rs +++ /dev/null @@ -1,28 +0,0 @@ -fn main() { - let n = 5; - - if n < 0 { - print!("{} is negative", n); - } else if n > 0 { - print!("{} is positive", n); - } else { - print!("{} is zero", n); - } - - let big_n = - if n < 10 && n > -10 { - println!(", and is a small number, increase ten-fold"); - - // This expression returns an `i32`. - 10 * n - } else { - println!(", and is a big number, reduce by two"); - - // This expression must return an `i32` as well. - n / 2 - // TODO ^ Try suppressing this expression with a semicolon. - }; - // ^ Don't forget to put a semicolon here! All `let` bindings need it. - - println!("{} -> {}", n, big_n); -} diff --git a/examples/flow_control/if_else/input.md b/examples/flow_control/if_else/input.md deleted file mode 100644 index 1f381bac84..0000000000 --- a/examples/flow_control/if_else/input.md +++ /dev/null @@ -1,6 +0,0 @@ -Branching with `if`-`else` is similar to other languages. Unlike many of them, -the boolean condition doesn't need to be surrounded by parentheses, and each -condition is followed by a block. `if`-`else` conditionals are expressions, -and, all branches must return the same type. - -{if_else.play} diff --git a/examples/flow_control/if_let/if_let.rs b/examples/flow_control/if_let/if_let.rs deleted file mode 100644 index 121ce9b721..0000000000 --- a/examples/flow_control/if_let/if_let.rs +++ /dev/null @@ -1,34 +0,0 @@ -fn main() { - // All have type `Option` - let number = Some(7); - let letter: Option = None; - let emoticon: Option = None; - - // The `if let` construct reads: "if `let` destructures `number` into - // `Some(i)`, evaluate the block (`{}`). - if let Some(i) = number { - println!("Matched {:?}!", i); - } - - // If you need to specify a failure, use an else: - if let Some(i) = letter { - println!("Matched {:?}!", i); - } else { - // Destructure failed. Change to the failure case. - println!("Didn't match a number. Let's go with a letter!"); - }; - - // Provide an altered failing condition. - let i_like_letters = false; - - if let Some(i) = emoticon { - println!("Matched {:?}!", i); - // Destructure failed. Evaluate an `else if` condition to see if the - // alternate failure branch should be taken: - } else if i_like_letters { - println!("Didn't match a number. Let's go with a letter!"); - } else { - // The condition evaluated false. This branch is the default: - println!("I don't like letters. Let's go with an emoticon :)!"); - }; -} diff --git a/examples/flow_control/if_let/input.md b/examples/flow_control/if_let/input.md deleted file mode 100644 index b053555cc7..0000000000 --- a/examples/flow_control/if_let/input.md +++ /dev/null @@ -1,31 +0,0 @@ -For some use cases, `match` is awkward. For example: - -```rust -// Make `optional` of type `Option` -let optional = Some(7); - -match optional { - Some(i) => { - println!("This is a really long string and `{:?}`", i); - // ^ Needed 2 indentations just so we could destructure - // `i` from the option. - }, - _ => {}, - // ^ Required because `match` is exhaustive. Doesn't it seem - // like wasted space? -}; - -``` - -`if let` is cleaner for this use case and in addition allows various -failure options to be specified: - -{if_let.play} - -### See also: - -[`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] - -[enum]: /custom_types/enum.html -[if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 -[option]: /std/option.html diff --git a/examples/flow_control/input.md b/examples/flow_control/input.md deleted file mode 100644 index 99e0a348e3..0000000000 --- a/examples/flow_control/input.md +++ /dev/null @@ -1,2 +0,0 @@ -An essential part of any programming languages are ways to modify control flow: -`if`/`else`, `for`, and others. Let's talk about them in Rust. diff --git a/examples/flow_control/loop/input.md b/examples/flow_control/loop/input.md deleted file mode 100644 index d79667783c..0000000000 --- a/examples/flow_control/loop/input.md +++ /dev/null @@ -1,7 +0,0 @@ -Rust provides a `loop` keyword to indicate an infinite loop. - -The `break` statement can be used to exit a loop at anytime, whereas the -`continue` statement can be used to skip the rest of the iteration and start a -new one. - -{loop.play} diff --git a/examples/flow_control/loop/loop.rs b/examples/flow_control/loop/loop.rs deleted file mode 100644 index 1718b2d9eb..0000000000 --- a/examples/flow_control/loop/loop.rs +++ /dev/null @@ -1,26 +0,0 @@ -fn main() { - let mut count = 0u32; - - println!("Let's count until infinity!"); - - // Infinite loop - loop { - count += 1; - - if count == 3 { - println!("three"); - - // Skip the rest of this iteration - continue; - } - - println!("{}", count); - - if count == 5 { - println!("OK, that's enough"); - - // Exit this loop - break; - } - } -} diff --git a/examples/flow_control/loop/nested/input.md b/examples/flow_control/loop/nested/input.md deleted file mode 100644 index f128b7ad34..0000000000 --- a/examples/flow_control/loop/nested/input.md +++ /dev/null @@ -1,5 +0,0 @@ -It's possible to `break` or `continue` outer loops when dealing with nested -loops. In these cases, the loops must be annotated with some `'label`, and the -label must be passed to the `break`/`continue` statement. - -{nested.play} diff --git a/examples/flow_control/loop/nested/nested.rs b/examples/flow_control/loop/nested/nested.rs deleted file mode 100644 index 32f1226d09..0000000000 --- a/examples/flow_control/loop/nested/nested.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![allow(unreachable_code)] - -fn main() { - 'outer: loop { - println!("Entered the outer loop"); - - 'inner: loop { - println!("Entered the inner loop"); - - // This would break only the inner loop - //break; - - // This breaks the outer loop - break 'outer; - } - - println!("This point will never be reached"); - } - - println!("Exited the outer loop"); -} diff --git a/examples/flow_control/loop/return/input.md b/examples/flow_control/loop/return/input.md deleted file mode 100644 index 54989239bf..0000000000 --- a/examples/flow_control/loop/return/input.md +++ /dev/null @@ -1,6 +0,0 @@ -One of the uses of a `loop` is to retry an operation until it succeded. If the -operation returns a value though, you might need to pass it to the rest of the -code: put it after the `break`, and it will be returned by the `loop` -expression. - -{return.play} diff --git a/examples/flow_control/loop/return/return.rs b/examples/flow_control/loop/return/return.rs deleted file mode 100644 index 41810b0999..0000000000 --- a/examples/flow_control/loop/return/return.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - let mut counter = 0; - - let result = loop { - counter += 1; - - if counter == 10 { - break counter * 2; - } - }; - - assert_eq!(result, 20); -} diff --git a/examples/flow_control/match/binding/binding.rs b/examples/flow_control/match/binding/binding.rs deleted file mode 100644 index 09a81d64d6..0000000000 --- a/examples/flow_control/match/binding/binding.rs +++ /dev/null @@ -1,19 +0,0 @@ -// A function `age` which returns a `u32`. -fn age() -> u32 { - 15 -} - -fn main() { - println!("Tell me type of person you are"); - - match age() { - 0 => println!("I'm not born yet I guess"), - // Could `match` 1 ... 12 directly but then what age - // would the child be? Instead, bind to `n` for the - // sequence of 1 .. 12. Now the age can be reported. - n @ 1 ... 12 => println!("I'm a child of age {:?}", n), - n @ 13 ... 19 => println!("I'm a teen of age {:?}", n), - // Nothing bound. Return the result. - n => println!("I'm an old person of age {:?}", n), - } -} diff --git a/examples/flow_control/match/binding/input.md b/examples/flow_control/match/binding/input.md deleted file mode 100644 index a19cec663e..0000000000 --- a/examples/flow_control/match/binding/input.md +++ /dev/null @@ -1,10 +0,0 @@ -Indirectly accessing a variable makes it impossible to branch and use that -variable without re-binding. `match` provides the `@` sigil for binding values to -names: - -{binding.play} - -### See also: -[functions][functions] - -[functions]: /fn.html diff --git a/examples/flow_control/match/destructuring/destructure_enum/enum.rs b/examples/flow_control/match/destructuring/destructure_enum/enum.rs deleted file mode 100644 index 4e252adf7c..0000000000 --- a/examples/flow_control/match/destructuring/destructure_enum/enum.rs +++ /dev/null @@ -1,40 +0,0 @@ -// `allow` required to silence warnings because only -// one variant is used. -#[allow(dead_code)] -enum Color { - // These 3 are specified solely by their name. - Red, - Blue, - Green, - // These likewise tie `u32` tuples to different names: color models. - RGB(u32, u32, u32), - HSV(u32, u32, u32), - HSL(u32, u32, u32), - CMY(u32, u32, u32), - CMYK(u32, u32, u32, u32), -} - -fn main() { - let color = Color::RGB(122, 17, 40); - // TODO ^ Try different variants for `color` - - println!("What color is it?"); - // An `enum` can be destructured using a `match`. - match color { - Color::Red => println!("The color is Red!"), - Color::Blue => println!("The color is Blue!"), - Color::Green => println!("The color is Green!"), - Color::RGB(r, g, b) => - println!("Red: {}, green: {}, and blue: {}!", r, g, b), - Color::HSV(h, s, v) => - println!("Hue: {}, saturation: {}, value: {}!", h, s, v), - Color::HSL(h, s, l) => - println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l), - Color::CMY(c, m, y) => - println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y), - Color::CMYK(c, m, y, k) => - println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!", - c, m, y, k), - // Don't need another arm because all variants have been examined - } -} diff --git a/examples/flow_control/match/destructuring/destructure_enum/input.md b/examples/flow_control/match/destructuring/destructure_enum/input.md deleted file mode 100644 index 14a65cad0b..0000000000 --- a/examples/flow_control/match/destructuring/destructure_enum/input.md +++ /dev/null @@ -1,11 +0,0 @@ -An `enum` is destructured similarly: - -{enum.play} - -### See also: - -[`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] - -[allow]: /attribute/unused.html -[color_models]: https://en.wikipedia.org/wiki/Color_model -[enum]: /custom_types/enum.html diff --git a/examples/flow_control/match/destructuring/destructure_pointers/input.md b/examples/flow_control/match/destructuring/destructure_pointers/input.md deleted file mode 100644 index a7373ad8d2..0000000000 --- a/examples/flow_control/match/destructuring/destructure_pointers/input.md +++ /dev/null @@ -1,8 +0,0 @@ -For pointers, a distinction needs to be made between destructuring -and dereferencing as they are different concepts which are used -differently from a language like `C`. - - * Dereferencing uses `*` - * Destructuring uses `&`, `ref`, and `ref mut` - -{pointers.play} diff --git a/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs b/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs deleted file mode 100644 index 9e59fc40d6..0000000000 --- a/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs +++ /dev/null @@ -1,50 +0,0 @@ -fn main() { - // Assign a reference of type `i32`. The `&` signifies there - // is a reference being assigned. - let reference = &4; - - match reference { - // If `reference`s is pattern matched against `&val`, it results - // in a comparison like: - // `&i32` - // `&val` - // ^ We see that if the matching `&`s are dropped, then the `i32` - // should be assigned to `val`. - &val => println!("Got a value via destructuring: {:?}", val), - } - - // To avoid the `&`, you dereference before matching. - match *reference { - val => println!("Got a value via dereferencing: {:?}", val), - } - - // What if you don't start with a reference? `reference` was a `&` - // because the right side was already a reference. This is not - // a reference because the right side is not one. - let _not_a_reference = 3; - - // Rust provides `ref` for exactly this purpose. It modifies the - // assignment so that a reference is created for the element; this - // reference is assigned. - let ref _is_a_reference = 3; - - // Accordingly, by defining 2 values without references, references - // can be retrieved via `ref` and `ref mut`. - let value = 5; - let mut mut_value = 6; - - // Use `ref` keyword to create a reference. - match value { - ref r => println!("Got a reference to a value: {:?}", r), - } - - // Use `ref mut` similarly. - match mut_value { - ref mut m => { - // Got a reference. Gotta dereference it before we can - // add anything to it. - *m += 10; - println!("We added 10. `mut_value`: {:?}", m); - }, - } -} diff --git a/examples/flow_control/match/destructuring/destructure_references/input.md b/examples/flow_control/match/destructuring/destructure_references/input.md deleted file mode 100644 index 0fabde2d6a..0000000000 --- a/examples/flow_control/match/destructuring/destructure_references/input.md +++ /dev/null @@ -1,10 +0,0 @@ -References and mutable references can be retrieved via -`ref` and `ref mut`: - -{ref.play} - -### See also: - -[Borrowing (`&`)][borrow] - -[borrow]: /borrow.html diff --git a/examples/flow_control/match/destructuring/destructure_references/ref.rs b/examples/flow_control/match/destructuring/destructure_references/ref.rs deleted file mode 100644 index 0ba0a72543..0000000000 --- a/examples/flow_control/match/destructuring/destructure_references/ref.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn main() { - // Start with two regular values - let value = 5; - let mut mut_value = 6; - - // To destructure into `&5` (reference to 5), use the `ref` keyword. - match value { - // `println!` can handle both regular values and references - // so it doesn't care which we give it. `r` will have type `&i32`. - ref r => println!("Got a reference to a value: {:?}", r), - } - - // Likewise, to get a mutable reference `&mut 6` back, - // `ref mut` is used. - match mut_value { - ref mut m => { - // Got a reference. Gotta dereference it before we can - // add anything to it. - *m += 10; - println!("We added 10. `mut_value`: {:?}", m); - }, - } -} diff --git a/examples/flow_control/match/destructuring/destructure_structures/input.md b/examples/flow_control/match/destructuring/destructure_structures/input.md deleted file mode 100644 index 1f1459dea5..0000000000 --- a/examples/flow_control/match/destructuring/destructure_structures/input.md +++ /dev/null @@ -1,7 +0,0 @@ -Similarly, a `struct` can be destructured as shown: - -{struct.play} - -### See also: - -[Structs](/custom_types/structs.html), [The ref pattern](/scope/borrow/ref.html) diff --git a/examples/flow_control/match/destructuring/destructure_structures/struct.rs b/examples/flow_control/match/destructuring/destructure_structures/struct.rs deleted file mode 100644 index 224f583deb..0000000000 --- a/examples/flow_control/match/destructuring/destructure_structures/struct.rs +++ /dev/null @@ -1,22 +0,0 @@ -fn main() { - struct Foo { x: (u32, u32), y: u32 } - - // destructure members of the struct - let foo = Foo { x: (1, 2), y: 3 }; - let Foo { x: (a, b), y } = foo; - - println!("a = {}, b = {}, y = {} ", a, b, y); - - // you can destructure structs and rename the variables, - // the order is not important - - let Foo { y: i, x: j } = foo; - println!("i = {:?}, j = {:?}", i, j); - - // and you can also ignore some variables: - let Foo { y, .. } = foo; - println!("y = {}", y); - - // this will give an error: pattern does not mention field `x` - // let Foo { y } = foo; -} diff --git a/examples/flow_control/match/destructuring/destructure_tuple/input.md b/examples/flow_control/match/destructuring/destructure_tuple/input.md deleted file mode 100644 index 5512b8fe69..0000000000 --- a/examples/flow_control/match/destructuring/destructure_tuple/input.md +++ /dev/null @@ -1,7 +0,0 @@ -Tuples can be destructured in a `match` as follows: - -{tuples.play} - -### See also: - -[Tuples](/primitives/tuples.html) diff --git a/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs b/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs deleted file mode 100644 index ab27884ca5..0000000000 --- a/examples/flow_control/match/destructuring/destructure_tuple/tuples.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - let pair = (0, -2); - // TODO ^ Try different values for `pair` - - println!("Tell me about {:?}", pair); - // Match can be used to destructure a tuple - match pair { - // Destructure the second - (0, y) => println!("First is `0` and `y` is `{:?}`", y), - (x, 0) => println!("`x` is `{:?}` and last is `0`", x), - _ => println!("It doesn't matter what they are"), - // `_` means don't bind the value to a variable - } -} diff --git a/examples/flow_control/match/destructuring/input.md b/examples/flow_control/match/destructuring/input.md deleted file mode 100644 index c86edcb071..0000000000 --- a/examples/flow_control/match/destructuring/input.md +++ /dev/null @@ -1 +0,0 @@ -A `match` block can destructure items in a variety of ways. diff --git a/examples/flow_control/match/guard/guard.rs b/examples/flow_control/match/guard/guard.rs deleted file mode 100644 index f246e4a0b2..0000000000 --- a/examples/flow_control/match/guard/guard.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - let pair = (2, -2); - // TODO ^ Try different values for `pair` - - println!("Tell me about {:?}", pair); - match pair { - (x, y) if x == y => println!("These are twins"), - // The ^ `if condition` part is a guard - (x, y) if x + y == 0 => println!("Antimatter, kaboom!"), - (x, _) if x % 2 == 1 => println!("The first one is odd"), - _ => println!("No correlation..."), - } -} diff --git a/examples/flow_control/match/guard/input.md b/examples/flow_control/match/guard/input.md deleted file mode 100644 index 9da083d2d1..0000000000 --- a/examples/flow_control/match/guard/input.md +++ /dev/null @@ -1,7 +0,0 @@ -A `match` *guard* can be added to filter the arm. - -{guard.play} - -### See also: - -[Tuples](/primitives/tuples.html) diff --git a/examples/flow_control/match/input.md b/examples/flow_control/match/input.md deleted file mode 100644 index 53c52a8959..0000000000 --- a/examples/flow_control/match/input.md +++ /dev/null @@ -1,4 +0,0 @@ -Rust provides pattern matching via the `match` keyword, which can be used like -a C `switch`. - -{match.play} diff --git a/examples/flow_control/match/match.rs b/examples/flow_control/match/match.rs deleted file mode 100644 index cf0c463e0e..0000000000 --- a/examples/flow_control/match/match.rs +++ /dev/null @@ -1,27 +0,0 @@ -fn main() { - let number = 13; - // TODO ^ Try different values for `number` - - println!("Tell me about {}", number); - match number { - // Match a single value - 1 => println!("One!"), - // Match several values - 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), - // Match an inclusive range - 13...19 => println!("A teen"), - // Handle the rest of cases - _ => println!("Ain't special"), - } - - let boolean = true; - // Match is an expression too - let binary = match boolean { - // The arms of a match must cover all the possible values - false => 0, - true => 1, - // TODO ^ Try commenting out one of these arms - }; - - println!("{} -> {}", boolean, binary); -} diff --git a/examples/flow_control/while/input.md b/examples/flow_control/while/input.md deleted file mode 100644 index 46befb7c1f..0000000000 --- a/examples/flow_control/while/input.md +++ /dev/null @@ -1,7 +0,0 @@ -The `while` keyword can be used to loop until a condition is met. - -Let's write the infamous [FizzBuzz][fizzbuzz] using a `while` loop. - -{while.play} - -[fizzbuzz]: https://en.wikipedia.org/wiki/Fizz_buzz diff --git a/examples/flow_control/while/while.rs b/examples/flow_control/while/while.rs deleted file mode 100644 index 3b37e550ad..0000000000 --- a/examples/flow_control/while/while.rs +++ /dev/null @@ -1,20 +0,0 @@ -fn main() { - // A counter variable - let mut n = 1; - - // Loop while `n` is less than 101 - while n < 101 { - if n % 15 == 0 { - println!("fizzbuzz"); - } else if n % 3 == 0 { - println!("fizz"); - } else if n % 5 == 0 { - println!("buzz"); - } else { - println!("{}", n); - } - - // Increment counter - n += 1; - } -} diff --git a/examples/flow_control/while_let/input.md b/examples/flow_control/while_let/input.md deleted file mode 100644 index b3b6fe306a..0000000000 --- a/examples/flow_control/while_let/input.md +++ /dev/null @@ -1,39 +0,0 @@ -Similar to `if let`, `while let` can make awkward `match` sequences -more tolerable. Consider the following sequence that increments `i`: - -```rust -// Make `optional` of type `Option` -let mut optional = Some(0); - -// Repeatedly try this test. -loop { - match optional { - // If `optional` destructures, evaluate the block. - Some(i) => { - if i > 9 { - println!("Greater than 9, quit!"); - optional = None; - } else { - println!("`i` is `{:?}`. Try again.", i); - optional = Some(i + 1); - } - // ^ Requires 3 indentations! - }, - // Quit the loop when the destructure fails: - _ => { break; } - // ^ Why should this be required? There must be a better way! - } -} -``` - -Using `while let` makes this sequence much nicer: - -{while_let.play} - -### See also: - -[`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] - -[enum]: /custom_types/enum.html -[option]: /std/option.html -[while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 diff --git a/examples/flow_control/while_let/while_let.rs b/examples/flow_control/while_let/while_let.rs deleted file mode 100644 index e2c11b4d00..0000000000 --- a/examples/flow_control/while_let/while_let.rs +++ /dev/null @@ -1,20 +0,0 @@ -fn main() { - // Make `optional` of type `Option` - let mut optional = Some(0); - - // This reads: "while `let` destructures `optional` into - // `Some(i)`, evaluate the block (`{}`). Else `break`. - while let Some(i) = optional { - if i > 9 { - println!("Greater than 9, quit!"); - optional = None; - } else { - println!("`i` is `{:?}`. Try again.", i); - optional = Some(i + 1); - } - // ^ Less rightward drift and doesn't require - // explicitly handling the failing case. - } - // ^ `if let` had additional optional `else`/`else if` - // clauses. `while let` does not have these. -} diff --git a/src/flow_control.md b/src/flow_control.md index cf0c99f028..4cd6d0d8e7 100644 --- a/src/flow_control.md +++ b/src/flow_control.md @@ -1 +1,4 @@ # Flow Control + +An essential part of any programming languages are ways to modify control flow: +`if`/`else`, `for`, and others. Let's talk about them in Rust. diff --git a/src/flow_control/for.md b/src/flow_control/for.md index abf5c8af57..21f9ac22b4 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -1 +1,31 @@ # for and range + +The `for in` construct can be used to iterate through an `Iterator`. +One of the easiest ways to create an iterator is to use the range +notation `a..b`. This yields values from `a` (inclusive) to `b` +(exclusive) in steps of one. + +Let's write FizzBuzz using `for` instead of `while`. + +```rust,editable +fn main() { + // `n` will take the values: 1, 2, ..., 100 in each iteration + for n in 1..101 { + if n % 15 == 0 { + println!("fizzbuzz"); + } else if n % 3 == 0 { + println!("fizz"); + } else if n % 5 == 0 { + println!("buzz"); + } else { + println!("{}", n); + } + } +} +``` + +###See also + +[Iterator][iter] + +[iter]: /trait/iter.html \ No newline at end of file diff --git a/src/flow_control/if_else.md b/src/flow_control/if_else.md index 148a691cb6..a8d53ee408 100644 --- a/src/flow_control/if_else.md +++ b/src/flow_control/if_else.md @@ -1 +1,37 @@ # if/else + +Branching with `if`-`else` is similar to other languages. Unlike many of them, +the boolean condition doesn't need to be surrounded by parentheses, and each +condition is followed by a block. `if`-`else` conditionals are expressions, +and, all branches must return the same type. + +```rust,editable +fn main() { + let n = 5; + + if n < 0 { + print!("{} is negative", n); + } else if n > 0 { + print!("{} is positive", n); + } else { + print!("{} is zero", n); + } + + let big_n = + if n < 10 && n > -10 { + println!(", and is a small number, increase ten-fold"); + + // This expression returns an `i32`. + 10 * n + } else { + println!(", and is a big number, reduce by two"); + + // This expression must return an `i32` as well. + n / 2 + // TODO ^ Try suppressing this expression with a semicolon. + }; + // ^ Don't forget to put a semicolon here! All `let` bindings need it. + + println!("{} -> {}", n, big_n); +} +``` \ No newline at end of file diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 72cfb74a1d..d94b961a1f 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -1 +1,68 @@ # if let + +For some use cases, `match` is awkward. For example: + +```rust +// Make `optional` of type `Option` +let optional = Some(7); + +match optional { + Some(i) => { + println!("This is a really long string and `{:?}`", i); + // ^ Needed 2 indentations just so we could destructure + // `i` from the option. + }, + _ => {}, + // ^ Required because `match` is exhaustive. Doesn't it seem + // like wasted space? +}; + +``` + +`if let` is cleaner for this use case and in addition allows various +failure options to be specified: + +```rust,editable +fn main() { + // All have type `Option` + let number = Some(7); + let letter: Option = None; + let emoticon: Option = None; + + // The `if let` construct reads: "if `let` destructures `number` into + // `Some(i)`, evaluate the block (`{}`). + if let Some(i) = number { + println!("Matched {:?}!", i); + } + + // If you need to specify a failure, use an else: + if let Some(i) = letter { + println!("Matched {:?}!", i); + } else { + // Destructure failed. Change to the failure case. + println!("Didn't match a number. Let's go with a letter!"); + }; + + // Provide an altered failing condition. + let i_like_letters = false; + + if let Some(i) = emoticon { + println!("Matched {:?}!", i); + // Destructure failed. Evaluate an `else if` condition to see if the + // alternate failure branch should be taken: + } else if i_like_letters { + println!("Didn't match a number. Let's go with a letter!"); + } else { + // The condition evaluated false. This branch is the default: + println!("I don't like letters. Let's go with an emoticon :)!"); + }; +} +``` + +### See also: + +[`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] + +[enum]: /custom_types/enum.html +[if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 +[option]: /std/option.html diff --git a/src/flow_control/loop.md b/src/flow_control/loop.md index baff0cf997..4a2405b7bf 100644 --- a/src/flow_control/loop.md +++ b/src/flow_control/loop.md @@ -1 +1,36 @@ # loop + +Rust provides a `loop` keyword to indicate an infinite loop. + +The `break` statement can be used to exit a loop at anytime, whereas the +`continue` statement can be used to skip the rest of the iteration and start a +new one. + +```rust,editable +fn main() { + let mut count = 0u32; + + println!("Let's count until infinity!"); + + // Infinite loop + loop { + count += 1; + + if count == 3 { + println!("three"); + + // Skip the rest of this iteration + continue; + } + + println!("{}", count); + + if count == 5 { + println!("OK, that's enough"); + + // Exit this loop + break; + } + } +} +``` \ No newline at end of file diff --git a/src/flow_control/loop/nested.md b/src/flow_control/loop/nested.md index a0653990fe..01c55a5594 100644 --- a/src/flow_control/loop/nested.md +++ b/src/flow_control/loop/nested.md @@ -1 +1,29 @@ # Nesting and labels + +It's possible to `break` or `continue` outer loops when dealing with nested +loops. In these cases, the loops must be annotated with some `'label`, and the +label must be passed to the `break`/`continue` statement. + +```rust,editable +#![allow(unreachable_code)] + +fn main() { + 'outer: loop { + println!("Entered the outer loop"); + + 'inner: loop { + println!("Entered the inner loop"); + + // This would break only the inner loop + //break; + + // This breaks the outer loop + break 'outer; + } + + println!("This point will never be reached"); + } + + println!("Exited the outer loop"); +} +``` \ No newline at end of file diff --git a/src/flow_control/loop/return.md b/src/flow_control/loop/return.md index bbde971463..866eecf98b 100644 --- a/src/flow_control/loop/return.md +++ b/src/flow_control/loop/return.md @@ -1 +1,22 @@ # Returning from loops + +One of the uses of a `loop` is to retry an operation until it succeded. If the +operation returns a value though, you might need to pass it to the rest of the +code: put it after the `break`, and it will be returned by the `loop` +expression. + +```rust,editable +fn main() { + let mut counter = 0; + + let result = loop { + counter += 1; + + if counter == 10 { + break counter * 2; + } + }; + + assert_eq!(result, 20); +} +``` \ No newline at end of file diff --git a/src/flow_control/match.md b/src/flow_control/match.md index 94a04c5700..fb0f56e3d2 100644 --- a/src/flow_control/match.md +++ b/src/flow_control/match.md @@ -1 +1,34 @@ # match + +Rust provides pattern matching via the `match` keyword, which can be used like +a C `switch`. + +```rust,editable +fn main() { + let number = 13; + // TODO ^ Try different values for `number` + + println!("Tell me about {}", number); + match number { + // Match a single value + 1 => println!("One!"), + // Match several values + 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), + // Match an inclusive range + 13...19 => println!("A teen"), + // Handle the rest of cases + _ => println!("Ain't special"), + } + + let boolean = true; + // Match is an expression too + let binary = match boolean { + // The arms of a match must cover all the possible values + false => 0, + true => 1, + // TODO ^ Try commenting out one of these arms + }; + + println!("{} -> {}", boolean, binary); +} +``` \ No newline at end of file diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index 7f93c67379..12c6341eda 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -1 +1,32 @@ # Binding + +Indirectly accessing a variable makes it impossible to branch and use that +variable without re-binding. `match` provides the `@` sigil for binding values to +names: + +```rust,editable +// A function `age` which returns a `u32`. +fn age() -> u32 { + 15 +} + +fn main() { + println!("Tell me type of person you are"); + + match age() { + 0 => println!("I'm not born yet I guess"), + // Could `match` 1 ... 12 directly but then what age + // would the child be? Instead, bind to `n` for the + // sequence of 1 .. 12. Now the age can be reported. + n @ 1 ... 12 => println!("I'm a child of age {:?}", n), + n @ 13 ... 19 => println!("I'm a teen of age {:?}", n), + // Nothing bound. Return the result. + n => println!("I'm an old person of age {:?}", n), + } +} +``` + +### See also: +[functions][functions] + +[functions]: /fn.html diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index 6c740766b1..c6c2bbc780 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -1 +1,3 @@ # Destructuring + +A `match` block can destructure items in a variety of ways. \ No newline at end of file diff --git a/src/flow_control/match/destructuring/destructure_enum.md b/src/flow_control/match/destructuring/destructure_enum.md index af2393bf06..1046e527ca 100644 --- a/src/flow_control/match/destructuring/destructure_enum.md +++ b/src/flow_control/match/destructuring/destructure_enum.md @@ -1 +1,54 @@ # enums + +An `enum` is destructured similarly: + +```rust,editable +// `allow` required to silence warnings because only +// one variant is used. +#[allow(dead_code)] +enum Color { + // These 3 are specified solely by their name. + Red, + Blue, + Green, + // These likewise tie `u32` tuples to different names: color models. + RGB(u32, u32, u32), + HSV(u32, u32, u32), + HSL(u32, u32, u32), + CMY(u32, u32, u32), + CMYK(u32, u32, u32, u32), +} + +fn main() { + let color = Color::RGB(122, 17, 40); + // TODO ^ Try different variants for `color` + + println!("What color is it?"); + // An `enum` can be destructured using a `match`. + match color { + Color::Red => println!("The color is Red!"), + Color::Blue => println!("The color is Blue!"), + Color::Green => println!("The color is Green!"), + Color::RGB(r, g, b) => + println!("Red: {}, green: {}, and blue: {}!", r, g, b), + Color::HSV(h, s, v) => + println!("Hue: {}, saturation: {}, value: {}!", h, s, v), + Color::HSL(h, s, l) => + println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l), + Color::CMY(c, m, y) => + println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y), + Color::CMYK(c, m, y, k) => + println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!", + c, m, y, k), + // Don't need another arm because all variants have been examined + } +} +``` + +### See also: + +[`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] + +[allow]: /attribute/unused.html +[color_models]: https://en.wikipedia.org/wiki/Color_model +[enum]: /custom_types/enum.html diff --git a/src/flow_control/match/destructuring/destructure_pointers.md b/src/flow_control/match/destructuring/destructure_pointers.md index 0bfff4b9b1..9f2ab60e42 100644 --- a/src/flow_control/match/destructuring/destructure_pointers.md +++ b/src/flow_control/match/destructuring/destructure_pointers.md @@ -1 +1,61 @@ # pointers/ref + +For pointers, a distinction needs to be made between destructuring +and dereferencing as they are different concepts which are used +differently from a language like `C`. + + * Dereferencing uses `*` + * Destructuring uses `&`, `ref`, and `ref mut` + +```rust,editable +fn main() { + // Assign a reference of type `i32`. The `&` signifies there + // is a reference being assigned. + let reference = &4; + + match reference { + // If `reference`s is pattern matched against `&val`, it results + // in a comparison like: + // `&i32` + // `&val` + // ^ We see that if the matching `&`s are dropped, then the `i32` + // should be assigned to `val`. + &val => println!("Got a value via destructuring: {:?}", val), + } + + // To avoid the `&`, you dereference before matching. + match *reference { + val => println!("Got a value via dereferencing: {:?}", val), + } + + // What if you don't start with a reference? `reference` was a `&` + // because the right side was already a reference. This is not + // a reference because the right side is not one. + let _not_a_reference = 3; + + // Rust provides `ref` for exactly this purpose. It modifies the + // assignment so that a reference is created for the element; this + // reference is assigned. + let ref _is_a_reference = 3; + + // Accordingly, by defining 2 values without references, references + // can be retrieved via `ref` and `ref mut`. + let value = 5; + let mut mut_value = 6; + + // Use `ref` keyword to create a reference. + match value { + ref r => println!("Got a reference to a value: {:?}", r), + } + + // Use `ref mut` similarly. + match mut_value { + ref mut m => { + // Got a reference. Gotta dereference it before we can + // add anything to it. + *m += 10; + println!("We added 10. `mut_value`: {:?}", m); + }, + } +} +``` \ No newline at end of file diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index 77bb0c627b..a4a23c90cc 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -1 +1,32 @@ # structs + +Similarly, a `struct` can be destructured as shown: + +```rust,editable +fn main() { + struct Foo { x: (u32, u32), y: u32 } + + // destructure members of the struct + let foo = Foo { x: (1, 2), y: 3 }; + let Foo { x: (a, b), y } = foo; + + println!("a = {}, b = {}, y = {} ", a, b, y); + + // you can destructure structs and rename the variables, + // the order is not important + + let Foo { y: i, x: j } = foo; + println!("i = {:?}, j = {:?}", i, j); + + // and you can also ignore some variables: + let Foo { y, .. } = foo; + println!("y = {}", y); + + // this will give an error: pattern does not mention field `x` + // let Foo { y } = foo; +} +``` + +### See also: + +[Structs](/custom_types/structs.html), [The ref pattern](/scope/borrow/ref.html) diff --git a/src/flow_control/match/destructuring/destructure_tuple.md b/src/flow_control/match/destructuring/destructure_tuple.md index 5757bde6ad..a29b1a802d 100644 --- a/src/flow_control/match/destructuring/destructure_tuple.md +++ b/src/flow_control/match/destructuring/destructure_tuple.md @@ -1 +1,24 @@ # tuples + +Tuples can be destructured in a `match` as follows: + +```rust,editable +fn main() { + let pair = (0, -2); + // TODO ^ Try different values for `pair` + + println!("Tell me about {:?}", pair); + // Match can be used to destructure a tuple + match pair { + // Destructure the second + (0, y) => println!("First is `0` and `y` is `{:?}`", y), + (x, 0) => println!("`x` is `{:?}` and last is `0`", x), + _ => println!("It doesn't matter what they are"), + // `_` means don't bind the value to a variable + } +} +``` + +### See also: + +[Tuples](/primitives/tuples.html) diff --git a/src/flow_control/match/guard.md b/src/flow_control/match/guard.md index ce68677ded..165306e190 100644 --- a/src/flow_control/match/guard.md +++ b/src/flow_control/match/guard.md @@ -1 +1,23 @@ # Guards + +A `match` *guard* can be added to filter the arm. + +```rust,editable +fn main() { + let pair = (2, -2); + // TODO ^ Try different values for `pair` + + println!("Tell me about {:?}", pair); + match pair { + (x, y) if x == y => println!("These are twins"), + // The ^ `if condition` part is a guard + (x, y) if x + y == 0 => println!("Antimatter, kaboom!"), + (x, _) if x % 2 == 1 => println!("The first one is odd"), + _ => println!("No correlation..."), + } +} +``` + +### See also: + +[Tuples](/primitives/tuples.html) diff --git a/src/flow_control/while.md b/src/flow_control/while.md index ab6710b007..2700b39cd6 100644 --- a/src/flow_control/while.md +++ b/src/flow_control/while.md @@ -1 +1,30 @@ # while + +The `while` keyword can be used to loop until a condition is met. + +Let's write the infamous [FizzBuzz][fizzbuzz] using a `while` loop. + +```rust,editable +fn main() { + // A counter variable + let mut n = 1; + + // Loop while `n` is less than 101 + while n < 101 { + if n % 15 == 0 { + println!("fizzbuzz"); + } else if n % 3 == 0 { + println!("fizz"); + } else if n % 5 == 0 { + println!("buzz"); + } else { + println!("{}", n); + } + + // Increment counter + n += 1; + } +} +``` + +[fizzbuzz]: https://en.wikipedia.org/wiki/Fizz_buzz diff --git a/src/flow_control/while_let.md b/src/flow_control/while_let.md index 34dd78197c..0f5fddc44c 100644 --- a/src/flow_control/while_let.md +++ b/src/flow_control/while_let.md @@ -1 +1,62 @@ # while let + +Similar to `if let`, `while let` can make awkward `match` sequences +more tolerable. Consider the following sequence that increments `i`: + +```rust +// Make `optional` of type `Option` +let mut optional = Some(0); + +// Repeatedly try this test. +loop { + match optional { + // If `optional` destructures, evaluate the block. + Some(i) => { + if i > 9 { + println!("Greater than 9, quit!"); + optional = None; + } else { + println!("`i` is `{:?}`. Try again.", i); + optional = Some(i + 1); + } + // ^ Requires 3 indentations! + }, + // Quit the loop when the destructure fails: + _ => { break; } + // ^ Why should this be required? There must be a better way! + } +} +``` + +Using `while let` makes this sequence much nicer: + +```rust,editable +fn main() { + // Make `optional` of type `Option` + let mut optional = Some(0); + + // This reads: "while `let` destructures `optional` into + // `Some(i)`, evaluate the block (`{}`). Else `break`. + while let Some(i) = optional { + if i > 9 { + println!("Greater than 9, quit!"); + optional = None; + } else { + println!("`i` is `{:?}`. Try again.", i); + optional = Some(i + 1); + } + // ^ Less rightward drift and doesn't require + // explicitly handling the failing case. + } + // ^ `if let` had additional optional `else`/`else if` + // clauses. `while let` does not have these. +} +``` + +### See also: + +[`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] + +[enum]: /custom_types/enum.html +[option]: /std/option.html +[while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 From 510826d12b37bae0741ffd882bfc31b8cd467f28 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 17:53:50 -0400 Subject: [PATCH 0643/1122] this isn't used --- examples/input.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 examples/input.md diff --git a/examples/input.md b/examples/input.md deleted file mode 100644 index cfeef30906..0000000000 --- a/examples/input.md +++ /dev/null @@ -1,3 +0,0 @@ -The chapters in this section are being worked on. These chapters are likely to -contain valid information, but may be unsorted or some of the concepts used -in them may have not been explained yet. From 4d64b6851ce2eb4e667ad1c05ae922d580237900 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:00:36 -0400 Subject: [PATCH 0644/1122] chapter: fn --- examples/fn/closures/anonymity/anonymity.rs | 17 --- examples/fn/closures/anonymity/input.md | 36 ------ examples/fn/closures/capture/capture.rs | 54 --------- examples/fn/closures/capture/input.md | 20 --- .../fn/closures/closure_examples/input.md | 1 - .../closure_examples/iter_any/input.md | 26 ---- .../closure_examples/iter_any/iter_any.rs | 17 --- .../closure_examples/iter_find/input.md | 26 ---- .../closure_examples/iter_find/iter_find.rs | 23 ---- examples/fn/closures/closures.rs | 23 ---- examples/fn/closures/input.md | 18 --- examples/fn/closures/input_functions/input.md | 17 --- .../input_functions/input_functions.rs | 18 --- .../fn/closures/input_parameters/input.md | 36 ------ .../input_parameters/input_parameters.rs | 50 -------- .../fn/closures/output_parameters/input.md | 31 ----- .../output_parameters/output_parameters.rs | 19 --- examples/fn/fn.rs | 37 ------ examples/fn/hof/hof.rs | 34 ------ examples/fn/hof/input.md | 13 -- examples/fn/input.md | 11 -- examples/fn/methods/input.md | 5 - examples/fn/methods/methods.rs | 107 ---------------- src/fn.md | 49 ++++++++ src/fn/closures.md | 43 +++++++ src/fn/closures/anonymity.md | 55 +++++++++ src/fn/closures/capture.md | 76 ++++++++++++ src/fn/closures/closure_examples.md | 2 + src/fn/closures/closure_examples/iter_any.md | 45 +++++++ src/fn/closures/closure_examples/iter_find.md | 50 ++++++++ src/fn/closures/input_functions.md | 37 ++++++ src/fn/closures/input_parameters.md | 88 ++++++++++++++ src/fn/closures/output_parameters.md | 52 ++++++++ src/fn/hof.md | 49 ++++++++ src/fn/methods.md | 114 ++++++++++++++++++ 35 files changed, 660 insertions(+), 639 deletions(-) delete mode 100644 examples/fn/closures/anonymity/anonymity.rs delete mode 100644 examples/fn/closures/anonymity/input.md delete mode 100644 examples/fn/closures/capture/capture.rs delete mode 100644 examples/fn/closures/capture/input.md delete mode 100644 examples/fn/closures/closure_examples/input.md delete mode 100644 examples/fn/closures/closure_examples/iter_any/input.md delete mode 100644 examples/fn/closures/closure_examples/iter_any/iter_any.rs delete mode 100644 examples/fn/closures/closure_examples/iter_find/input.md delete mode 100644 examples/fn/closures/closure_examples/iter_find/iter_find.rs delete mode 100644 examples/fn/closures/closures.rs delete mode 100644 examples/fn/closures/input.md delete mode 100644 examples/fn/closures/input_functions/input.md delete mode 100644 examples/fn/closures/input_functions/input_functions.rs delete mode 100644 examples/fn/closures/input_parameters/input.md delete mode 100644 examples/fn/closures/input_parameters/input_parameters.rs delete mode 100644 examples/fn/closures/output_parameters/input.md delete mode 100644 examples/fn/closures/output_parameters/output_parameters.rs delete mode 100644 examples/fn/fn.rs delete mode 100644 examples/fn/hof/hof.rs delete mode 100644 examples/fn/hof/input.md delete mode 100644 examples/fn/input.md delete mode 100644 examples/fn/methods/input.md delete mode 100644 examples/fn/methods/methods.rs diff --git a/examples/fn/closures/anonymity/anonymity.rs b/examples/fn/closures/anonymity/anonymity.rs deleted file mode 100644 index 6c02274d3c..0000000000 --- a/examples/fn/closures/anonymity/anonymity.rs +++ /dev/null @@ -1,17 +0,0 @@ -// `F` must implement `Fn` for a closure which takes no -// inputs and returns nothing - exactly what is required -// for `print`. -fn apply(f: F) where - F: Fn() { - f(); -} - -fn main() { - let x = 7; - - // Capture `x` into an anonymous type and implement - // `Fn` for it. Store it in `print`. - let print = || println!("{}", x); - - apply(print); -} diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md deleted file mode 100644 index c6b241f94a..0000000000 --- a/examples/fn/closures/anonymity/input.md +++ /dev/null @@ -1,36 +0,0 @@ -Closures succinctly capture variables from enclosing scopes. Does this have -any consequences? It surely does. Observe how using a closure as a function -parameter requires [generics], which is necessary because of how they are -defined: - -```rust -// `F` must be generic. -fn apply(f: F) where - F: FnOnce() { - f(); -} -``` - -When a closure is defined, the compiler implicitly creates a new -anonymous structure to store the captured variables inside, meanwhile -implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or -`FnOnce` for this unknown type. This type is assigned to the variable which -is stored until calling. - -Since this new type is of unknown type, any usage in a function will require -generics. However, an unbounded type parameter `` would still be ambiguous -and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or -`FnOnce` (which it implements) is sufficient to specify its type. - -{anonymity.play} - -### See also: - -[A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], -and [`FnOnce`][fn_once] - -[generics]: /generics.html -[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html -[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html -[thorough_analysis]: https://huonw.github.io/blog/2015/05/finding-closure-in-rust/ diff --git a/examples/fn/closures/capture/capture.rs b/examples/fn/closures/capture/capture.rs deleted file mode 100644 index 6cb5d86ae7..0000000000 --- a/examples/fn/closures/capture/capture.rs +++ /dev/null @@ -1,54 +0,0 @@ -fn main() { - use std::mem; - - let color = "green"; - - // A closure to print `color` which immediately borrows (`&`) - // `color` and stores the borrow and closure in the `print` - // variable. It will remain borrowed until `print` goes out of - // scope. `println!` only requires `by reference` so it doesn't - // impose anything more restrictive. - let print = || println!("`color`: {}", color); - - // Call the closure using the borrow. - print(); - print(); - - let mut count = 0; - - // A closure to increment `count` could take either `&mut count` - // or `count` but `&mut count` is less restrictive so it takes - // that. Immediately borrows `count`. - // - // A `mut` is required on `inc` because a `&mut` is stored inside. - // Thus, calling the closure mutates the closure which requires - // a `mut`. - let mut inc = || { - count += 1; - println!("`count`: {}", count); - }; - - // Call the closure. - inc(); - inc(); - - //let reborrow = &mut count; - // ^ TODO: try uncommenting this line. - - // A non-copy type. - let movable = Box::new(3); - - // `mem::drop` requires `T` so this must take by value. A copy type - // would copy into the closure leaving the original untouched. - // A non-copy must move and so `movable` immediately moves into - // the closure. - let consume = || { - println!("`movable`: {:?}", movable); - mem::drop(movable); - }; - - // `consume` consumes the variable so this can only be called once. - consume(); - //consume(); - // ^ TODO: Try uncommenting this line. -} diff --git a/examples/fn/closures/capture/input.md b/examples/fn/closures/capture/input.md deleted file mode 100644 index 49ba656bc4..0000000000 --- a/examples/fn/closures/capture/input.md +++ /dev/null @@ -1,20 +0,0 @@ -Closures are inherently flexible and will do what the functionality requires -to make the closure work without annotation. This allows capturing to -flexibly adapt to the use case, sometimes moving and sometimes borrowing. -Closures can capture variables: - -* by reference: `&T` -* by mutable reference: `&mut T` -* by value: `T` - -They preferentially capture variables by reference and only go lower when -required. - -{capture.play} - -### See also: - -[`Box`][box] and [`std::mem::drop`][drop] - -[box]: /std/box.html -[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/examples/fn/closures/closure_examples/input.md b/examples/fn/closures/closure_examples/input.md deleted file mode 100644 index 29bd47f83f..0000000000 --- a/examples/fn/closures/closure_examples/input.md +++ /dev/null @@ -1 +0,0 @@ -This section contains a few examples of using closures from the `std` library. \ No newline at end of file diff --git a/examples/fn/closures/closure_examples/iter_any/input.md b/examples/fn/closures/closure_examples/iter_any/input.md deleted file mode 100644 index ad00ca4227..0000000000 --- a/examples/fn/closures/closure_examples/iter_any/input.md +++ /dev/null @@ -1,26 +0,0 @@ -`Iterator::any` is a function which when passed an iterator, will return -`true` if any element satisfies the predicate. Otherwise `false`. Its -signature: - -```rust -pub trait Iterator { - // The type being iterated over. - type Item; - - // `any` takes `&mut self` meaning the caller may be borrowed - // and modified, but not consumed. - fn any(&mut self, f: F) -> bool where - // `FnMut` meaning any captured variable may at most be - // modified, not consumed. `Self::Item` states it takes - // arguments to the closure by value. - F: FnMut(Self::Item) -> bool {} -} -``` - -{iter_any.play} - -### See also: - -[`std::iter::Iterator::any`][any] - -[any]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/examples/fn/closures/closure_examples/iter_any/iter_any.rs b/examples/fn/closures/closure_examples/iter_any/iter_any.rs deleted file mode 100644 index 4df37c5700..0000000000 --- a/examples/fn/closures/closure_examples/iter_any/iter_any.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn main() { - let vec1 = vec![1, 2, 3]; - let vec2 = vec![4, 5, 6]; - - // `iter()` for vecs yields `&i32`. Destructure to `i32`. - println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); - // `into_iter()` for vecs yields `i32`. No destructuring required. - println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2)); - - let array1 = [1, 2, 3]; - let array2 = [4, 5, 6]; - - // `iter()` for arrays yields `&i32`. - println!("2 in array1: {}", array1.iter() .any(|&x| x == 2)); - // `into_iter()` for arrays unusually yields `&i32`. - println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2)); -} diff --git a/examples/fn/closures/closure_examples/iter_find/input.md b/examples/fn/closures/closure_examples/iter_find/input.md deleted file mode 100644 index cfc114f0cd..0000000000 --- a/examples/fn/closures/closure_examples/iter_find/input.md +++ /dev/null @@ -1,26 +0,0 @@ -`Iterator::find` is a function which when passed an iterator, will return -the first element which satisfies the predicate as an `Option`. Its -signature: - -```rust -pub trait Iterator { - // The type being iterated over. - type Item; - - // `find` takes `&mut self` meaning the caller may be borrowed - // and modified, but not consumed. - fn find

(&mut self, predicate: P) -> Option where - // `FnMut` meaning any captured variable may at most be - // modified, not consumed. `&Self::Item` states it takes - // arguments to the closure by reference. - P: FnMut(&Self::Item) -> bool {} -} -``` - -{iter_find.play} - -### See also: - -[`std::iter::Iterator::find`][find] - -[find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/examples/fn/closures/closure_examples/iter_find/iter_find.rs b/examples/fn/closures/closure_examples/iter_find/iter_find.rs deleted file mode 100644 index 854da02530..0000000000 --- a/examples/fn/closures/closure_examples/iter_find/iter_find.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn main() { - let vec1 = vec![1, 2, 3]; - let vec2 = vec![4, 5, 6]; - - // `iter()` for vecs yields `&i32`. - let mut iter = vec1.iter(); - // `into_iter()` for vecs yields `i32`. - let mut into_iter = vec2.into_iter(); - - // A reference to what is yielded is `&&i32`. Destructure to `i32`. - println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2)); - // A reference to what is yielded is `&i32`. Destructure to `i32`. - println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2)); - - let array1 = [1, 2, 3]; - let array2 = [4, 5, 6]; - - // `iter()` for arrays yields `&i32` - println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2)); - // `into_iter()` for arrays unusually yields `&i32` - println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2)); -} - diff --git a/examples/fn/closures/closures.rs b/examples/fn/closures/closures.rs deleted file mode 100644 index dc5f197219..0000000000 --- a/examples/fn/closures/closures.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn main() { - // Increment via closures and functions. - fn function (i: i32) -> i32 { i + 1 } - - // Closures are anonymous, here we are binding them to references - // Annotation is identical to function annotation but is optional - // as are the `{}` wrapping the body. These nameless functions - // are assigned to appropriately named variables. - let closure_annotated = |i: i32| -> i32 { i + 1 }; - let closure_inferred = |i | i + 1 ; - - let i = 1; - // Call the function and closures. - println!("function: {}", function(i)); - println!("closure_annotated: {}", closure_annotated(i)); - println!("closure_inferred: {}", closure_inferred(i)); - - // A closure taking no arguments which returns an `i32`. - // The return type is inferred. - let one = || 1; - println!("closure returning one: {}", one()); - -} diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md deleted file mode 100644 index 3ba6cd22a7..0000000000 --- a/examples/fn/closures/input.md +++ /dev/null @@ -1,18 +0,0 @@ -Closures in Rust, also called lambdas, are functions that can capture -the enclosing environment. For example, a closure that captures the x -variable: -```Rust -|val| val + x -``` - -The syntax and capabilities of closures make them very convenient for -on the fly usage. Calling a closure is exactly like calling a function. -However, both input and return types *can* be inferred and input -variable names *must* be specified. - -Other characteristics of closures include: -* using `||` instead of `()` around input variables. -* optional body delimination (`{}`) for a single expression (mandatory otherwise). -* the ability to capture the outer environment variables. - -{closures.play} diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md deleted file mode 100644 index 214b1338ff..0000000000 --- a/examples/fn/closures/input_functions/input.md +++ /dev/null @@ -1,17 +0,0 @@ -Since closures may be used as arguments, you might wonder if the same can be said -about functions. And indeed they can! If you declare a function that takes a -closure as parameter, then any function that satisfies the trait bound of that -closure can be passed as a parameter. - -{input_functions.play} - -As an additional note, the `Fn`, `FnMut`, and `FnOnce` `traits` dictate how -a closure captures variables from the enclosing scope. - -### See also: - -[`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] - -[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html -[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs deleted file mode 100644 index ea7382c67d..0000000000 --- a/examples/fn/closures/input_functions/input_functions.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Define a function which takes a generic `F` argument -// bounded by `Fn`, and calls it -fn call_me(f: F) { - f(); -} - -// Define a wrapper function satisfying the `Fn` bound -fn function() { - println!("I'm a function!"); -} - -fn main() { - // Define a closure satisfying the `Fn` bound - let closure = || println!("I'm a closure!"); - - call_me(closure); - call_me(function); -} diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md deleted file mode 100644 index fd4adf9021..0000000000 --- a/examples/fn/closures/input_parameters/input.md +++ /dev/null @@ -1,36 +0,0 @@ -While Rust chooses how to capture variables on the fly mostly without type -annotation, this ambiguity is not allowed when writing functions. When -taking a closure as an input parameter, the closure's complete type must be -annotated using one of a few `traits`. In order of decreasing restriction, -they are: - -* `Fn`: the closure captures by reference (`&T`) -* `FnMut`: the closure captures by mutable reference (`&mut T`) -* `FnOnce`: the closure captures by value (`T`) - -On a variable-by-variable basis, the compiler will capture variables in the -least restrictive manner possible. - -For instance, consider a parameter annotated as `FnOnce`. This specifies -that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler -will ultimately choose based on how the captured variables are used in the -closure. - -This is because if a move is possible, then any type of borrow should also -be possible. Note that the reverse is not true. If the parameter is -annotated as `Fn`, then capturing variables by `&mut T` or `T` are not -allowed. - -In the following example, try swapping the usage of `Fn`, `FnMut`, and -`FnOnce` to see what happens: - -{input_parameters.play} - -### See also: - -[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce] - -[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html -[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html -[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs deleted file mode 100644 index dadfa2e44b..0000000000 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ /dev/null @@ -1,50 +0,0 @@ -// A function which takes a closure as an argument and calls it. -fn apply(f: F) where - // The closure takes no input and returns nothing. - F: FnOnce() { - // ^ TODO: Try changing this to `Fn` or `FnMut`. - - f(); -} - -// A function which takes a closure and returns an `i32`. -fn apply_to_3(f: F) -> i32 where - // The closure takes an `i32` and returns an `i32`. - F: Fn(i32) -> i32 { - - f(3) -} - -fn main() { - use std::mem; - - let greeting = "hello"; - // A non-copy type. - // `to_owned` creates owned data from borrowed one - let mut farewell = "goodbye".to_owned(); - - // Capture 2 variables: `greeting` by reference and - // `farewell` by value. - let diary = || { - // `greeting` is by reference: requires `Fn`. - println!("I said {}.", greeting); - - // Mutation forces `farewell` to be captured by - // mutable reference. Now requires `FnMut`. - farewell.push_str("!!!"); - println!("Then I screamed {}.", farewell); - println!("Now I can sleep. zzzzz"); - - // Manually calling drop forces `farewell` to - // be captured by value. Now requires `FnOnce`. - mem::drop(farewell); - }; - - // Call the function which applies the closure. - apply(diary); - - // `double` satisfies `apply_to_3`'s trait bound - let double = |x| 2 * x; - - println!("3 doubled: {}", apply_to_3(double)); -} diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md deleted file mode 100644 index e0f41d432d..0000000000 --- a/examples/fn/closures/output_parameters/input.md +++ /dev/null @@ -1,31 +0,0 @@ -Closures as input parameters are possible, so returning closures as -output parameters should also be possible. However, returning closure types -are problematic because Rust currently only supports returning concrete -(non-generic) types. Anonymous closure types are, by definition, unknown -and so returning a closure is only possible by making it concrete. This -can be done via boxing. - -The valid traits for returns are slightly different than before: - -* `Fn`: normal -* `FnMut`: normal -* `FnOnce`: There are some unusual things at play here, so the [`FnBox`][fnbox] - type is currently needed, and is unstable. This is expected to change in - the future. - -Beyond this, the `move` keyword must be used, which signals that all captures -occur by value. This is required because any captures by reference would be -dropped as soon as the function exited, leaving invalid references in the -closure. - -{output_parameters.play} - -### See also: - -[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. - -[box]: /std/box.html -[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html -[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html -[generics]: /generics.html diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs deleted file mode 100644 index 0e09cd3c9a..0000000000 --- a/examples/fn/closures/output_parameters/output_parameters.rs +++ /dev/null @@ -1,19 +0,0 @@ -fn create_fn() -> Box { - let text = "Fn".to_owned(); - - Box::new(move || println!("This is a: {}", text)) -} - -fn create_fnmut() -> Box { - let text = "FnMut".to_owned(); - - Box::new(move || println!("This is a: {}", text)) -} - -fn main() { - let fn_plain = create_fn(); - let mut fn_mut = create_fnmut(); - - fn_plain(); - fn_mut(); -} diff --git a/examples/fn/fn.rs b/examples/fn/fn.rs deleted file mode 100644 index db70707a8c..0000000000 --- a/examples/fn/fn.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Unlike C/C++, there's no restriction on the order of function definitions -fn main() { - // We can use this function here, and define it somewhere later - fizzbuzz_to(100); -} - -// Function that returns a boolean value -fn is_divisible_by(lhs: u32, rhs: u32) -> bool { - // Corner case, early return - if rhs == 0 { - return false; - } - - // This is an expression, the `return` keyword is not necessary here - lhs % rhs == 0 -} - -// Functions that "don't" return a value, actually return the unit type `()` -fn fizzbuzz(n: u32) -> () { - if is_divisible_by(n, 15) { - println!("fizzbuzz"); - } else if is_divisible_by(n, 3) { - println!("fizz"); - } else if is_divisible_by(n, 5) { - println!("buzz"); - } else { - println!("{}", n); - } -} - -// When a function returns `()`, the return type can be omitted from the -// signature -fn fizzbuzz_to(n: u32) { - for n in 1..n + 1 { - fizzbuzz(n); - } -} diff --git a/examples/fn/hof/hof.rs b/examples/fn/hof/hof.rs deleted file mode 100644 index 78c187ee71..0000000000 --- a/examples/fn/hof/hof.rs +++ /dev/null @@ -1,34 +0,0 @@ -fn is_odd(n: u32) -> bool { - n % 2 == 1 -} - -fn main() { - println!("Find the sum of all the squared odd numbers under 1000"); - let upper = 1000; - - // Imperative approach - // Declare accumulator variable - let mut acc = 0; - // Iterate: 0, 1, 2, ... to infinity - for n in 0.. { - // Square the number - let n_squared = n * n; - - if n_squared >= upper { - // Break loop if exceeded the upper limit - break; - } else if is_odd(n_squared) { - // Accumulate value, if it's odd - acc += n_squared; - } - } - println!("imperative style: {}", acc); - - // Functional approach - let sum_of_squared_odd_numbers: u32 = - (0..).map(|n| n * n) // All natural numbers squared - .take_while(|&n| n < upper) // Below upper limit - .filter(|&n| is_odd(n)) // That are odd - .fold(0, |sum, i| sum + i); // Sum them - println!("functional style: {}", sum_of_squared_odd_numbers); -} \ No newline at end of file diff --git a/examples/fn/hof/input.md b/examples/fn/hof/input.md deleted file mode 100644 index 118b59317f..0000000000 --- a/examples/fn/hof/input.md +++ /dev/null @@ -1,13 +0,0 @@ -Rust provides Higher Order Functions (HOF). These are functions that -take one or more functions and/or produce a more useful function. HOFs -and lazy iterators give Rust its functional flavor. - -{hof.play} - -[Option][option] -and -[Iterator][iter] -implement their fair share of HOFs. - -[option]: https://doc.rust-lang.org/core/option/enum.Option.html -[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/fn/input.md b/examples/fn/input.md deleted file mode 100644 index 05829a6722..0000000000 --- a/examples/fn/input.md +++ /dev/null @@ -1,11 +0,0 @@ -Functions are declared using the `fn` keyword. Its arguments are type -annotated, just like variables, and, if the function returns a value, the -return type must be specified after an arrow `->`. - -The final expression in the function will be used as return value. -Alternatively, the `return` statement can be used to return a value earlier -from within the function, even from inside loops or `if`s. - -Let's rewrite FizzBuzz using functions! - -{fn.play} diff --git a/examples/fn/methods/input.md b/examples/fn/methods/input.md deleted file mode 100644 index 1bedf82be7..0000000000 --- a/examples/fn/methods/input.md +++ /dev/null @@ -1,5 +0,0 @@ -Methods are functions attached to objects. These methods have access to the -data of the object and its other methods via the `self` keyword. Methods are -defined under an `impl` block. - -{methods.play} diff --git a/examples/fn/methods/methods.rs b/examples/fn/methods/methods.rs deleted file mode 100644 index ca45c7a9be..0000000000 --- a/examples/fn/methods/methods.rs +++ /dev/null @@ -1,107 +0,0 @@ -struct Point { - x: f64, - y: f64, -} - -// Implementation block, all `Point` methods go in here -impl Point { - // This is a static method - // Static methods don't need to be called by an instance - // These methods are generally used as constructors - fn origin() -> Point { - Point { x: 0.0, y: 0.0 } - } - - // Another static method, taking two arguments: - fn new(x: f64, y: f64) -> Point { - Point { x: x, y: y } - } -} - -struct Rectangle { - p1: Point, - p2: Point, -} - -impl Rectangle { - // This is an instance method - // `&self` is sugar for `self: &Self`, where `Self` is the type of the - // caller object. In this case `Self` = `Rectangle` - fn area(&self) -> f64 { - // `self` gives access to the struct fields via the dot operator - let Point { x: x1, y: y1 } = self.p1; - let Point { x: x2, y: y2 } = self.p2; - - // `abs` is a `f64` method that returns the absolute value of the - // caller - ((x1 - x2) * (y1 - y2)).abs() - } - - fn perimeter(&self) -> f64 { - let Point { x: x1, y: y1 } = self.p1; - let Point { x: x2, y: y2 } = self.p2; - - 2.0 * ((x1 - x2).abs() + (y1 - y2).abs()) - } - - // This method requires the caller object to be mutable - // `&mut self` desugars to `self: &mut Self` - fn translate(&mut self, x: f64, y: f64) { - self.p1.x += x; - self.p2.x += x; - - self.p1.y += y; - self.p2.y += y; - } -} - -// `Pair` owns resources: two heap allocated integers -struct Pair(Box, Box); - -impl Pair { - // This method "consumes" the resources of the caller object - // `self` desugars to `self: Self` - fn destroy(self) { - // Destructure `self` - let Pair(first, second) = self; - - println!("Destroying Pair({}, {})", first, second); - - // `first` and `second` go out of scope and get freed - } -} - -fn main() { - let rectangle = Rectangle { - // Static methods are called using double colons - p1: Point::origin(), - p2: Point::new(3.0, 4.0), - }; - - // Instance methods are called using the dot operator - // Note that the first argument `&self` is implicitly passed, i.e. - // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)` - println!("Rectangle perimeter: {}", rectangle.perimeter()); - println!("Rectangle area: {}", rectangle.area()); - - let mut square = Rectangle { - p1: Point::origin(), - p2: Point::new(1.0, 1.0), - }; - - // Error! `rectangle` is immutable, but this method requires a mutable - // object - //rectangle.translate(1.0, 0.0); - // TODO ^ Try uncommenting this line - - // Okay! Mutable objects can call mutable methods - square.translate(1.0, 1.0); - - let pair = Pair(Box::new(1), Box::new(2)); - - pair.destroy(); - - // Error! Previous `destroy` call "consumed" `pair` - //pair.destroy(); - // TODO ^ Try uncommenting this line -} diff --git a/src/fn.md b/src/fn.md index 0c5faf50f8..337bf3bc2d 100644 --- a/src/fn.md +++ b/src/fn.md @@ -1 +1,50 @@ # Functions + +Functions are declared using the `fn` keyword. Its arguments are type +annotated, just like variables, and, if the function returns a value, the +return type must be specified after an arrow `->`. + +The final expression in the function will be used as return value. +Alternatively, the `return` statement can be used to return a value earlier +from within the function, even from inside loops or `if`s. + +Let's rewrite FizzBuzz using functions! + +```rust,editable +// Unlike C/C++, there's no restriction on the order of function definitions +fn main() { + // We can use this function here, and define it somewhere later + fizzbuzz_to(100); +} + +// Function that returns a boolean value +fn is_divisible_by(lhs: u32, rhs: u32) -> bool { + // Corner case, early return + if rhs == 0 { + return false; + } + + // This is an expression, the `return` keyword is not necessary here + lhs % rhs == 0 +} + +// Functions that "don't" return a value, actually return the unit type `()` +fn fizzbuzz(n: u32) -> () { + if is_divisible_by(n, 15) { + println!("fizzbuzz"); + } else if is_divisible_by(n, 3) { + println!("fizz"); + } else if is_divisible_by(n, 5) { + println!("buzz"); + } else { + println!("{}", n); + } +} + +// When a function returns `()`, the return type can be omitted from the +// signature +fn fizzbuzz_to(n: u32) { + for n in 1..n + 1 { + fizzbuzz(n); + } +} diff --git a/src/fn/closures.md b/src/fn/closures.md index 713d5db4dc..1c3c17b9db 100644 --- a/src/fn/closures.md +++ b/src/fn/closures.md @@ -1 +1,44 @@ # Closures + +Closures in Rust, also called lambdas, are functions that can capture +the enclosing environment. For example, a closure that captures the x +variable: +```Rust +|val| val + x +``` + +The syntax and capabilities of closures make them very convenient for +on the fly usage. Calling a closure is exactly like calling a function. +However, both input and return types *can* be inferred and input +variable names *must* be specified. + +Other characteristics of closures include: +* using `||` instead of `()` around input variables. +* optional body delimination (`{}`) for a single expression (mandatory otherwise). +* the ability to capture the outer environment variables. + +```rust,editable +fn main() { + // Increment via closures and functions. + fn function (i: i32) -> i32 { i + 1 } + + // Closures are anonymous, here we are binding them to references + // Annotation is identical to function annotation but is optional + // as are the `{}` wrapping the body. These nameless functions + // are assigned to appropriately named variables. + let closure_annotated = |i: i32| -> i32 { i + 1 }; + let closure_inferred = |i | i + 1 ; + + let i = 1; + // Call the function and closures. + println!("function: {}", function(i)); + println!("closure_annotated: {}", closure_annotated(i)); + println!("closure_inferred: {}", closure_inferred(i)); + + // A closure taking no arguments which returns an `i32`. + // The return type is inferred. + let one = || 1; + println!("closure returning one: {}", one()); + +} +``` \ No newline at end of file diff --git a/src/fn/closures/anonymity.md b/src/fn/closures/anonymity.md index c00413ad12..d6881bc389 100644 --- a/src/fn/closures/anonymity.md +++ b/src/fn/closures/anonymity.md @@ -1 +1,56 @@ # Type anonymity + +Closures succinctly capture variables from enclosing scopes. Does this have +any consequences? It surely does. Observe how using a closure as a function +parameter requires [generics], which is necessary because of how they are +defined: + +```rust +// `F` must be generic. +fn apply(f: F) where + F: FnOnce() { + f(); +} +``` + +When a closure is defined, the compiler implicitly creates a new +anonymous structure to store the captured variables inside, meanwhile +implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` for this unknown type. This type is assigned to the variable which +is stored until calling. + +Since this new type is of unknown type, any usage in a function will require +generics. However, an unbounded type parameter `` would still be ambiguous +and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` (which it implements) is sufficient to specify its type. + +```rust,editable +// `F` must implement `Fn` for a closure which takes no +// inputs and returns nothing - exactly what is required +// for `print`. +fn apply(f: F) where + F: Fn() { + f(); +} + +fn main() { + let x = 7; + + // Capture `x` into an anonymous type and implement + // `Fn` for it. Store it in `print`. + let print = || println!("{}", x); + + apply(print); +} +``` + +### See also: + +[A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], +and [`FnOnce`][fn_once] + +[generics]: /generics.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html +[thorough_analysis]: https://huonw.github.io/blog/2015/05/finding-closure-in-rust/ diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index e297a98caa..361676acbe 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -1 +1,77 @@ # Capturing + +Closures are inherently flexible and will do what the functionality requires +to make the closure work without annotation. This allows capturing to +flexibly adapt to the use case, sometimes moving and sometimes borrowing. +Closures can capture variables: + +* by reference: `&T` +* by mutable reference: `&mut T` +* by value: `T` + +They preferentially capture variables by reference and only go lower when +required. + +```rust,editable +fn main() { + use std::mem; + + let color = "green"; + + // A closure to print `color` which immediately borrows (`&`) + // `color` and stores the borrow and closure in the `print` + // variable. It will remain borrowed until `print` goes out of + // scope. `println!` only requires `by reference` so it doesn't + // impose anything more restrictive. + let print = || println!("`color`: {}", color); + + // Call the closure using the borrow. + print(); + print(); + + let mut count = 0; + + // A closure to increment `count` could take either `&mut count` + // or `count` but `&mut count` is less restrictive so it takes + // that. Immediately borrows `count`. + // + // A `mut` is required on `inc` because a `&mut` is stored inside. + // Thus, calling the closure mutates the closure which requires + // a `mut`. + let mut inc = || { + count += 1; + println!("`count`: {}", count); + }; + + // Call the closure. + inc(); + inc(); + + //let reborrow = &mut count; + // ^ TODO: try uncommenting this line. + + // A non-copy type. + let movable = Box::new(3); + + // `mem::drop` requires `T` so this must take by value. A copy type + // would copy into the closure leaving the original untouched. + // A non-copy must move and so `movable` immediately moves into + // the closure. + let consume = || { + println!("`movable`: {:?}", movable); + mem::drop(movable); + }; + + // `consume` consumes the variable so this can only be called once. + consume(); + //consume(); + // ^ TODO: Try uncommenting this line. +} +``` + +### See also: + +[`Box`][box] and [`std::mem::drop`][drop] + +[box]: /std/box.html +[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/src/fn/closures/closure_examples.md b/src/fn/closures/closure_examples.md index f2dbaef2b7..2455523ad9 100644 --- a/src/fn/closures/closure_examples.md +++ b/src/fn/closures/closure_examples.md @@ -1 +1,3 @@ # Examples in `std` + +This section contains a few examples of using closures from the `std` library. \ No newline at end of file diff --git a/src/fn/closures/closure_examples/iter_any.md b/src/fn/closures/closure_examples/iter_any.md index 294bb8c20e..fc171d2bc7 100644 --- a/src/fn/closures/closure_examples/iter_any.md +++ b/src/fn/closures/closure_examples/iter_any.md @@ -1 +1,46 @@ # Iterator::any + +`Iterator::any` is a function which when passed an iterator, will return +`true` if any element satisfies the predicate. Otherwise `false`. Its +signature: + +```rust +pub trait Iterator { + // The type being iterated over. + type Item; + + // `any` takes `&mut self` meaning the caller may be borrowed + // and modified, but not consumed. + fn any(&mut self, f: F) -> bool where + // `FnMut` meaning any captured variable may at most be + // modified, not consumed. `Self::Item` states it takes + // arguments to the closure by value. + F: FnMut(Self::Item) -> bool {} +} +``` + +```rust,ignore +fn main() { + let vec1 = vec![1, 2, 3]; + let vec2 = vec![4, 5, 6]; + + // `iter()` for vecs yields `&i32`. Destructure to `i32`. + println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); + // `into_iter()` for vecs yields `i32`. No destructuring required. + println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2)); + + let array1 = [1, 2, 3]; + let array2 = [4, 5, 6]; + + // `iter()` for arrays yields `&i32`. + println!("2 in array1: {}", array1.iter() .any(|&x| x == 2)); + // `into_iter()` for arrays unusually yields `&i32`. + println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2)); +} +``` + +### See also: + +[`std::iter::Iterator::any`][any] + +[any]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/src/fn/closures/closure_examples/iter_find.md b/src/fn/closures/closure_examples/iter_find.md index 2b944b3a9d..1dc4ce8c3e 100644 --- a/src/fn/closures/closure_examples/iter_find.md +++ b/src/fn/closures/closure_examples/iter_find.md @@ -1 +1,51 @@ # Iterator::find + +`Iterator::find` is a function which when passed an iterator, will return +the first element which satisfies the predicate as an `Option`. Its +signature: + +```rust +pub trait Iterator { + // The type being iterated over. + type Item; + + // `find` takes `&mut self` meaning the caller may be borrowed + // and modified, but not consumed. + fn find

(&mut self, predicate: P) -> Option where + // `FnMut` meaning any captured variable may at most be + // modified, not consumed. `&Self::Item` states it takes + // arguments to the closure by reference. + P: FnMut(&Self::Item) -> bool {} +} +``` + +```rust,editable +fn main() { + let vec1 = vec![1, 2, 3]; + let vec2 = vec![4, 5, 6]; + + // `iter()` for vecs yields `&i32`. + let mut iter = vec1.iter(); + // `into_iter()` for vecs yields `i32`. + let mut into_iter = vec2.into_iter(); + + // A reference to what is yielded is `&&i32`. Destructure to `i32`. + println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2)); + // A reference to what is yielded is `&i32`. Destructure to `i32`. + println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2)); + + let array1 = [1, 2, 3]; + let array2 = [4, 5, 6]; + + // `iter()` for arrays yields `&i32` + println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2)); + // `into_iter()` for arrays unusually yields `&i32` + println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2)); +} +``` + +### See also: + +[`std::iter::Iterator::find`][find] + +[find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/src/fn/closures/input_functions.md b/src/fn/closures/input_functions.md index 323cfcf44e..0cf9cd1cb1 100644 --- a/src/fn/closures/input_functions.md +++ b/src/fn/closures/input_functions.md @@ -1 +1,38 @@ # Input functions + +Since closures may be used as arguments, you might wonder if the same can be said +about functions. And indeed they can! If you declare a function that takes a +closure as parameter, then any function that satisfies the trait bound of that +closure can be passed as a parameter. + +```rust,editable +// Define a function which takes a generic `F` argument +// bounded by `Fn`, and calls it +fn call_me(f: F) { + f(); +} + +// Define a wrapper function satisfying the `Fn` bound +fn function() { + println!("I'm a function!"); +} + +fn main() { + // Define a closure satisfying the `Fn` bound + let closure = || println!("I'm a closure!"); + + call_me(closure); + call_me(function); +} +``` + +As an additional note, the `Fn`, `FnMut`, and `FnOnce` `traits` dictate how +a closure captures variables from the enclosing scope. + +### See also: + +[`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] + +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/src/fn/closures/input_parameters.md b/src/fn/closures/input_parameters.md index 61b2d9f0d6..c97a4d1390 100644 --- a/src/fn/closures/input_parameters.md +++ b/src/fn/closures/input_parameters.md @@ -1 +1,89 @@ # As input parameters + +While Rust chooses how to capture variables on the fly mostly without type +annotation, this ambiguity is not allowed when writing functions. When +taking a closure as an input parameter, the closure's complete type must be +annotated using one of a few `traits`. In order of decreasing restriction, +they are: + +* `Fn`: the closure captures by reference (`&T`) +* `FnMut`: the closure captures by mutable reference (`&mut T`) +* `FnOnce`: the closure captures by value (`T`) + +On a variable-by-variable basis, the compiler will capture variables in the +least restrictive manner possible. + +For instance, consider a parameter annotated as `FnOnce`. This specifies +that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler +will ultimately choose based on how the captured variables are used in the +closure. + +This is because if a move is possible, then any type of borrow should also +be possible. Note that the reverse is not true. If the parameter is +annotated as `Fn`, then capturing variables by `&mut T` or `T` are not +allowed. + +In the following example, try swapping the usage of `Fn`, `FnMut`, and +`FnOnce` to see what happens: + +```rust,editable +// A function which takes a closure as an argument and calls it. +fn apply(f: F) where + // The closure takes no input and returns nothing. + F: FnOnce() { + // ^ TODO: Try changing this to `Fn` or `FnMut`. + + f(); +} + +// A function which takes a closure and returns an `i32`. +fn apply_to_3(f: F) -> i32 where + // The closure takes an `i32` and returns an `i32`. + F: Fn(i32) -> i32 { + + f(3) +} + +fn main() { + use std::mem; + + let greeting = "hello"; + // A non-copy type. + // `to_owned` creates owned data from borrowed one + let mut farewell = "goodbye".to_owned(); + + // Capture 2 variables: `greeting` by reference and + // `farewell` by value. + let diary = || { + // `greeting` is by reference: requires `Fn`. + println!("I said {}.", greeting); + + // Mutation forces `farewell` to be captured by + // mutable reference. Now requires `FnMut`. + farewell.push_str("!!!"); + println!("Then I screamed {}.", farewell); + println!("Now I can sleep. zzzzz"); + + // Manually calling drop forces `farewell` to + // be captured by value. Now requires `FnOnce`. + mem::drop(farewell); + }; + + // Call the function which applies the closure. + apply(diary); + + // `double` satisfies `apply_to_3`'s trait bound + let double = |x| 2 * x; + + println!("3 doubled: {}", apply_to_3(double)); +} +``` + +### See also: + +[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce] + +[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index 1028097a4b..b3fae31472 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -1 +1,53 @@ # As output parameters + +Closures as input parameters are possible, so returning closures as +output parameters should also be possible. However, returning closure types +are problematic because Rust currently only supports returning concrete +(non-generic) types. Anonymous closure types are, by definition, unknown +and so returning a closure is only possible by making it concrete. This +can be done via boxing. + +The valid traits for returns are slightly different than before: + +* `Fn`: normal +* `FnMut`: normal +* `FnOnce`: There are some unusual things at play here, so the [`FnBox`][fnbox] + type is currently needed, and is unstable. This is expected to change in + the future. + +Beyond this, the `move` keyword must be used, which signals that all captures +occur by value. This is required because any captures by reference would be +dropped as soon as the function exited, leaving invalid references in the +closure. + +```rust,editable +fn create_fn() -> Box { + let text = "Fn".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn create_fnmut() -> Box { + let text = "FnMut".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn main() { + let fn_plain = create_fn(); + let mut fn_mut = create_fnmut(); + + fn_plain(); + fn_mut(); +} +``` + +### See also: + +[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. + +[box]: /std/box.html +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html +[generics]: /generics.html diff --git a/src/fn/hof.md b/src/fn/hof.md index be7450e7fb..c5c28c45bd 100644 --- a/src/fn/hof.md +++ b/src/fn/hof.md @@ -1 +1,50 @@ # Higher Order Functions + +Rust provides Higher Order Functions (HOF). These are functions that +take one or more functions and/or produce a more useful function. HOFs +and lazy iterators give Rust its functional flavor. + +```rust,editable +fn is_odd(n: u32) -> bool { + n % 2 == 1 +} + +fn main() { + println!("Find the sum of all the squared odd numbers under 1000"); + let upper = 1000; + + // Imperative approach + // Declare accumulator variable + let mut acc = 0; + // Iterate: 0, 1, 2, ... to infinity + for n in 0.. { + // Square the number + let n_squared = n * n; + + if n_squared >= upper { + // Break loop if exceeded the upper limit + break; + } else if is_odd(n_squared) { + // Accumulate value, if it's odd + acc += n_squared; + } + } + println!("imperative style: {}", acc); + + // Functional approach + let sum_of_squared_odd_numbers: u32 = + (0..).map(|n| n * n) // All natural numbers squared + .take_while(|&n| n < upper) // Below upper limit + .filter(|&n| is_odd(n)) // That are odd + .fold(0, |sum, i| sum + i); // Sum them + println!("functional style: {}", sum_of_squared_odd_numbers); +} +``` + +[Option][option] +and +[Iterator][iter] +implement their fair share of HOFs. + +[option]: https://doc.rust-lang.org/core/option/enum.Option.html +[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/src/fn/methods.md b/src/fn/methods.md index 8f834183a1..8e8c10ced4 100644 --- a/src/fn/methods.md +++ b/src/fn/methods.md @@ -1 +1,115 @@ # Methods + +Methods are functions attached to objects. These methods have access to the +data of the object and its other methods via the `self` keyword. Methods are +defined under an `impl` block. + +```rust,editable +struct Point { + x: f64, + y: f64, +} + +// Implementation block, all `Point` methods go in here +impl Point { + // This is a static method + // Static methods don't need to be called by an instance + // These methods are generally used as constructors + fn origin() -> Point { + Point { x: 0.0, y: 0.0 } + } + + // Another static method, taking two arguments: + fn new(x: f64, y: f64) -> Point { + Point { x: x, y: y } + } +} + +struct Rectangle { + p1: Point, + p2: Point, +} + +impl Rectangle { + // This is an instance method + // `&self` is sugar for `self: &Self`, where `Self` is the type of the + // caller object. In this case `Self` = `Rectangle` + fn area(&self) -> f64 { + // `self` gives access to the struct fields via the dot operator + let Point { x: x1, y: y1 } = self.p1; + let Point { x: x2, y: y2 } = self.p2; + + // `abs` is a `f64` method that returns the absolute value of the + // caller + ((x1 - x2) * (y1 - y2)).abs() + } + + fn perimeter(&self) -> f64 { + let Point { x: x1, y: y1 } = self.p1; + let Point { x: x2, y: y2 } = self.p2; + + 2.0 * ((x1 - x2).abs() + (y1 - y2).abs()) + } + + // This method requires the caller object to be mutable + // `&mut self` desugars to `self: &mut Self` + fn translate(&mut self, x: f64, y: f64) { + self.p1.x += x; + self.p2.x += x; + + self.p1.y += y; + self.p2.y += y; + } +} + +// `Pair` owns resources: two heap allocated integers +struct Pair(Box, Box); + +impl Pair { + // This method "consumes" the resources of the caller object + // `self` desugars to `self: Self` + fn destroy(self) { + // Destructure `self` + let Pair(first, second) = self; + + println!("Destroying Pair({}, {})", first, second); + + // `first` and `second` go out of scope and get freed + } +} + +fn main() { + let rectangle = Rectangle { + // Static methods are called using double colons + p1: Point::origin(), + p2: Point::new(3.0, 4.0), + }; + + // Instance methods are called using the dot operator + // Note that the first argument `&self` is implicitly passed, i.e. + // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)` + println!("Rectangle perimeter: {}", rectangle.perimeter()); + println!("Rectangle area: {}", rectangle.area()); + + let mut square = Rectangle { + p1: Point::origin(), + p2: Point::new(1.0, 1.0), + }; + + // Error! `rectangle` is immutable, but this method requires a mutable + // object + //rectangle.translate(1.0, 0.0); + // TODO ^ Try uncommenting this line + + // Okay! Mutable objects can call mutable methods + square.translate(1.0, 1.0); + + let pair = Pair(Box::new(1), Box::new(2)); + + pair.destroy(); + + // Error! Previous `destroy` call "consumed" `pair` + //pair.destroy(); + // TODO ^ Try uncommenting this line +} +``` \ No newline at end of file From d89db9939fdc2d96ad0fa5318182e0e5dd701015 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:09:28 -0400 Subject: [PATCH 0645/1122] chapter: traits --- examples/trait/clone/clone.rs | 42 ---------------- examples/trait/clone/input.md | 10 ---- examples/trait/derive/derive.rs | 45 ----------------- examples/trait/derive/input.md | 30 ------------ examples/trait/drop/drop.rs | 40 --------------- examples/trait/drop/input.md | 14 ------ examples/trait/input.md | 9 ---- examples/trait/iter/input.md | 16 ------ examples/trait/iter/iter.rs | 68 -------------------------- examples/trait/ops/input.md | 17 ------- examples/trait/ops/operator.rs | 41 ---------------- examples/trait/trait.rs | 68 -------------------------- src/trait.md | 79 ++++++++++++++++++++++++++++++ src/trait/clone.md | 54 +++++++++++++++++++++ src/trait/derive.md | 77 +++++++++++++++++++++++++++++ src/trait/drop.md | 56 +++++++++++++++++++++ src/trait/iter.md | 86 +++++++++++++++++++++++++++++++++ src/trait/ops.md | 60 +++++++++++++++++++++++ 18 files changed, 412 insertions(+), 400 deletions(-) delete mode 100644 examples/trait/clone/clone.rs delete mode 100644 examples/trait/clone/input.md delete mode 100644 examples/trait/derive/derive.rs delete mode 100644 examples/trait/derive/input.md delete mode 100644 examples/trait/drop/drop.rs delete mode 100644 examples/trait/drop/input.md delete mode 100644 examples/trait/input.md delete mode 100644 examples/trait/iter/input.md delete mode 100644 examples/trait/iter/iter.rs delete mode 100644 examples/trait/ops/input.md delete mode 100644 examples/trait/ops/operator.rs delete mode 100644 examples/trait/trait.rs diff --git a/examples/trait/clone/clone.rs b/examples/trait/clone/clone.rs deleted file mode 100644 index 2cad5db2b0..0000000000 --- a/examples/trait/clone/clone.rs +++ /dev/null @@ -1,42 +0,0 @@ -// A unit struct without resources -#[derive(Debug, Clone, Copy)] -struct Nil; - -// A tuple struct with resources that implements the `Clone` trait -#[derive(Clone, Debug)] -struct Pair(Box, Box); - -fn main() { - // Instantiate `Nil` - let nil = Nil; - // Copy `Nil`, there are no resources to move - let copied_nil = nil; - - // Both `Nil`s can be used independently - println!("original: {:?}", nil); - println!("copy: {:?}", copied_nil); - - // Instantiate `Pair` - let pair = Pair(Box::new(1), Box::new(2)); - println!("original: {:?}", pair); - - // Copy `pair` into `moved_pair`, moves resources - let moved_pair = pair; - println!("copy: {:?}", moved_pair); - - // Error! `pair` has lost its resources - //println!("original: {:?}", pair); - // TODO ^ Try uncommenting this line - - // Clone `moved_pair` into `cloned_pair` (resources are included) - let cloned_pair = moved_pair.clone(); - // Drop the original pair using std::mem::drop - drop(moved_pair); - - // Error! `moved_pair` has been dropped - //println!("copy: {:?}", moved_pair); - // TODO ^ Try uncommenting this line - - // The result from .clone() can still be used! - println!("clone: {:?}", cloned_pair); -} diff --git a/examples/trait/clone/input.md b/examples/trait/clone/input.md deleted file mode 100644 index ce61cb2384..0000000000 --- a/examples/trait/clone/input.md +++ /dev/null @@ -1,10 +0,0 @@ -When dealing with resources, the default behavior is to transfer them during -assignments or function calls. However, sometimes we need to make a -copy of the resource as well. - -The [`Clone`][clone] trait helps us do exactly this. Most commonly, we can -use the `.clone()` method defined by the `Clone` trait. - -{clone.play} - -[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html \ No newline at end of file diff --git a/examples/trait/derive/derive.rs b/examples/trait/derive/derive.rs deleted file mode 100644 index 48e5962610..0000000000 --- a/examples/trait/derive/derive.rs +++ /dev/null @@ -1,45 +0,0 @@ -// `Centimeters`, a tuple struct that can be compared -#[derive(PartialEq, PartialOrd)] -struct Centimeters(f64); - -// `Inches`, a tuple struct that can be printed -#[derive(Debug)] -struct Inches(i32); - -impl Inches { - fn to_centimeters(&self) -> Centimeters { - let &Inches(inches) = self; - - Centimeters(inches as f64 * 2.54) - } -} - -// `Seconds`, a tuple struct no additional attributes -struct Seconds(i32); - -fn main() { - let _one_second = Seconds(1); - - // Error: `Seconds` can't be printed; it doesn't implement the `Debug` trait - //println!("One second looks like: {:?}", _one_second); - // TODO ^ Try uncommenting this line - - // Error: `Seconds` can't be compared; it doesn't implement the `PartialEq` trait - //let _this_is_true = (_one_second == _one_second); - // TODO ^ Try uncommenting this line - - let foot = Inches(12); - - println!("One foot equals {:?}", foot); - - let meter = Centimeters(100.0); - - let cmp = - if foot.to_centimeters() < meter { - "smaller" - } else { - "bigger" - }; - - println!("One foot is {} than one meter.", cmp); -} diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md deleted file mode 100644 index 12c9104caf..0000000000 --- a/examples/trait/derive/input.md +++ /dev/null @@ -1,30 +0,0 @@ -The compiler is capable of providing basic implementations for some traits via -the `#[derive]` [attribute][attribute]. These traits can still be -manually implemented if a more complex behavior is required. - -The following is a list of derivable traits: -* Comparison traits: - [`Eq`][eq], [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord] -* [`Clone`][clone], to create `T` from `&T` via a copy. -* [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics' -* [`Hash`][hash], to compute a hash from `&T`. -* [`Default`][default], to create an empty instance of a data type. -* `Zero`, to create a zero instance of a numeric data type. -* [`Debug`][debug], to format a value using the `{:?}` formatter. - -{derive.play} - -### See also: -[`derive`][derive] - -[attribute]: /attribute.html -[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html -[partial-eq]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html -[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html -[partial-ord]: https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html -[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html -[copy]: https://doc.rust-lang.org/core/marker/trait.Copy.html -[hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html -[default]: https://doc.rust-lang.org/std/default/trait.Default.html -[debug]: https://doc.rust-lang.org/std/fmt/trait.Debug.html -[derive]: https://doc.rust-lang.org/reference/attributes.html#derive diff --git a/examples/trait/drop/drop.rs b/examples/trait/drop/drop.rs deleted file mode 100644 index ff11b47724..0000000000 --- a/examples/trait/drop/drop.rs +++ /dev/null @@ -1,40 +0,0 @@ -struct Droppable { - name: &'static str, -} - -// This trivial implementation of `drop` adds a print to console. -impl Drop for Droppable { - fn drop(&mut self) { - println!("> Dropping {}", self.name); - } -} - -fn main() { - let _a = Droppable { name: "a" }; - - // block A - { - let _b = Droppable { name: "b" }; - - // block B - { - let _c = Droppable { name: "c" }; - let _d = Droppable { name: "d" }; - - println!("Exiting block B"); - } - println!("Just exited block B"); - - println!("Exiting block A"); - } - println!("Just exited block A"); - - // Variable can be manually dropped using the `drop` function - drop(_a); - // TODO ^ Try commenting this line - - println!("end of the main function"); - - // `_a` *won't* be `drop`ed again here, because it already has been - // (manually) `drop`ed -} diff --git a/examples/trait/drop/input.md b/examples/trait/drop/input.md deleted file mode 100644 index a2a0eb157d..0000000000 --- a/examples/trait/drop/input.md +++ /dev/null @@ -1,14 +0,0 @@ -The [`Drop`][Drop] trait only has one method: `drop`, which is called automatically -when an object goes out of scope. The main use of the `Drop` trait is to free the -resources that the implementor instance owns. - -`Box`, `Vec`, `String`, `File`, and `Process` are some examples of types that -implement the `Drop` trait to free resources. The `Drop` trait can also be -manually implemented for any custom data type. - -The following example adds a print to console to the `drop` function to announce -when it is called. - -{drop.play} - -[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html \ No newline at end of file diff --git a/examples/trait/input.md b/examples/trait/input.md deleted file mode 100644 index 5cf22ca476..0000000000 --- a/examples/trait/input.md +++ /dev/null @@ -1,9 +0,0 @@ -A `trait` is a collection of methods defined for an unknown type: -`Self`. They can access other methods declared in the same trait. - -Traits can be implemented for any data type. In the example below, -we define `Animal`, a group of methods. The `Animal` `trait` is -then implemented for the `Sheep` data type, allowing the use of -methods from `Animal` with a `Sheep`. - -{trait.play} diff --git a/examples/trait/iter/input.md b/examples/trait/iter/input.md deleted file mode 100644 index 7e00d32293..0000000000 --- a/examples/trait/iter/input.md +++ /dev/null @@ -1,16 +0,0 @@ -The `Iterator` trait is used to implement iterators over collections such as arrays. - -The trait requires only a method to be defined for the `next` element, -which may be manually defined in an `impl` block or automatically -defined (as in arrays and ranges). - -As a point of convenience for common situations, the `for` construct -turns some collections into iterators using the [`.into_iterator()`][intoiter] method. - -Methods that can be accessed using the `Iterator` trait in addition -to those shown in the example below can be found [here][iter]. - -{iter.play} - -[intoiter]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html -[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/trait/iter/iter.rs b/examples/trait/iter/iter.rs deleted file mode 100644 index 476c64c0b1..0000000000 --- a/examples/trait/iter/iter.rs +++ /dev/null @@ -1,68 +0,0 @@ -struct Fibonacci { - curr: u32, - next: u32, -} - -// Implement `Iterator` for `Fibonacci`. -// The `Iterator` trait only requires a method to be defined for the `next` element. -impl Iterator for Fibonacci { - type Item = u32; - - // Here, we define the sequence using `.curr` and `.next`. - // The return type is `Option`: - // * When the `Iterator` is finished, `None` is returned. - // * Otherwise, the next value is wrapped in `Some` and returned. - fn next(&mut self) -> Option { - let new_next = self.curr + self.next; - - self.curr = self.next; - self.next = new_next; - - // Since there's no endpoint to a Fibonacci sequence, the `Iterator` - // will never return `None`, and `Some` is always returned. - Some(self.curr) - } -} - -// Returns a Fibonacci sequence generator -fn fibonacci() -> Fibonacci { - Fibonacci { curr: 1, next: 1 } -} - -fn main() { - // `0..3` is an `Iterator` that generates: 0, 1, and 2. - let mut sequence = 0..3; - - println!("Four consecutive `next` calls on 0..3"); - println!("> {:?}", sequence.next()); - println!("> {:?}", sequence.next()); - println!("> {:?}", sequence.next()); - println!("> {:?}", sequence.next()); - - // `for` works through an `Iterator` until it returns `None`. - // Each `Some` value is unwrapped and bound to a variable (here, `i`). - println!("Iterate through 0..3 using `for`"); - for i in 0..3 { - println!("> {}", i); - } - - // The `take(n)` method reduces an `Iterator` to its first `n` terms. - println!("The first four terms of the Fibonacci sequence are: "); - for i in fibonacci().take(4) { - println!("> {}", i); - } - - // The `skip(n)` method shortens an `Iterator` by dropping its first `n` terms. - println!("The next four terms of the Fibonacci sequence are: "); - for i in fibonacci().skip(4).take(4) { - println!("> {}", i); - } - - let array = [1u32, 3, 3, 7]; - - // The `iter` method produces an `Iterator` over an array/slice. - println!("Iterate the following array {:?}", &array); - for i in array.iter() { - println!("> {}", i); - } -} \ No newline at end of file diff --git a/examples/trait/ops/input.md b/examples/trait/ops/input.md deleted file mode 100644 index 9421fd65bf..0000000000 --- a/examples/trait/ops/input.md +++ /dev/null @@ -1,17 +0,0 @@ -In Rust, many of the operators can be overloaded via traits. That is, some operators can -be used to accomplish different tasks based on their input arguments. This is possible -because operators are syntactic sugar for method calls. For example, the `+` operator in -`a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` -trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. - -A list of the traits, such as `Add`, that overload operators is available [here][ops]. - -{operator.play} - -###See Also - -[Add][add], [Syntax Index][syntax] - -[add]: https://doc.rust-lang.org/core/ops/trait.Add.html -[ops]: https://doc.rust-lang.org/core/ops/ -[syntax]: https://doc.rust-lang.org/book/syntax-index.html diff --git a/examples/trait/ops/operator.rs b/examples/trait/ops/operator.rs deleted file mode 100644 index 215ca92bd6..0000000000 --- a/examples/trait/ops/operator.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::ops; - -struct Foo; -struct Bar; - -#[derive(Debug)] -struct FooBar; - -#[derive(Debug)] -struct BarFoo; - -// The `std::ops::Add` trait is used to specify the functionality of `+`. -// Here, we make `Add` - the trait for addition with a RHS of type `Bar`. -// The following block implements the operation: Foo + Bar = FooBar -impl ops::Add for Foo { - type Output = FooBar; - - fn add(self, _rhs: Bar) -> FooBar { - println!("> Foo.add(Bar) was called"); - - FooBar - } -} - -// By reversing the types, we end up implementing non-commutative addition. -// Here, we make `Add` - the trait for addition with a RHS of type `Foo`. -// This block implements the operation: Bar + Foo = BarFoo -impl ops::Add for Bar { - type Output = BarFoo; - - fn add(self, _rhs: Foo) -> BarFoo { - println!("> Bar.add(Foo) was called"); - - BarFoo - } -} - -fn main() { - println!("Foo + Bar = {:?}", Foo + Bar); - println!("Bar + Foo = {:?}", Bar + Foo); -} diff --git a/examples/trait/trait.rs b/examples/trait/trait.rs deleted file mode 100644 index dc01a26577..0000000000 --- a/examples/trait/trait.rs +++ /dev/null @@ -1,68 +0,0 @@ -struct Sheep { naked: bool, name: &'static str } - -trait Animal { - // Static method signature; `Self` refers to the implementor type. - fn new(name: &'static str) -> Self; - - // Instance method signatures; these will return a string. - fn name(&self) -> &'static str; - fn noise(&self) -> &'static str; - - // Traits can provide default method definitions. - fn talk(&self) { - println!("{} says {}", self.name(), self.noise()); - } -} - -impl Sheep { - fn is_naked(&self) -> bool { - self.naked - } - - fn shear(&mut self) { - if self.is_naked() { - // Implementor methods can use the implementor's trait methods. - println!("{} is already naked...", self.name()); - } else { - println!("{} gets a haircut!", self.name); - - self.naked = true; - } - } -} - -// Implement the `Animal` trait for `Sheep`. -impl Animal for Sheep { - // `Self` is the implementor type: `Sheep`. - fn new(name: &'static str) -> Sheep { - Sheep { name: name, naked: false } - } - - fn name(&self) -> &'static str { - self.name - } - - fn noise(&self) -> &'static str { - if self.is_naked() { - "baaaaah?" - } else { - "baaaaah!" - } - } - - // Default trait methods can be overridden. - fn talk(&self) { - // For example, we can add some quiet contemplation. - println!("{} pauses briefly... {}", self.name, self.noise()); - } -} - -fn main() { - // Type annotation is necessary in this case. - let mut dolly: Sheep = Animal::new("Dolly"); - // TODO ^ Try removing the type annotations. - - dolly.talk(); - dolly.shear(); - dolly.talk(); -} diff --git a/src/trait.md b/src/trait.md index 445d444b17..7878d4742b 100644 --- a/src/trait.md +++ b/src/trait.md @@ -1 +1,80 @@ # Traits + +A `trait` is a collection of methods defined for an unknown type: +`Self`. They can access other methods declared in the same trait. + +Traits can be implemented for any data type. In the example below, +we define `Animal`, a group of methods. The `Animal` `trait` is +then implemented for the `Sheep` data type, allowing the use of +methods from `Animal` with a `Sheep`. + +```rust,editable +struct Sheep { naked: bool, name: &'static str } + +trait Animal { + // Static method signature; `Self` refers to the implementor type. + fn new(name: &'static str) -> Self; + + // Instance method signatures; these will return a string. + fn name(&self) -> &'static str; + fn noise(&self) -> &'static str; + + // Traits can provide default method definitions. + fn talk(&self) { + println!("{} says {}", self.name(), self.noise()); + } +} + +impl Sheep { + fn is_naked(&self) -> bool { + self.naked + } + + fn shear(&mut self) { + if self.is_naked() { + // Implementor methods can use the implementor's trait methods. + println!("{} is already naked...", self.name()); + } else { + println!("{} gets a haircut!", self.name); + + self.naked = true; + } + } +} + +// Implement the `Animal` trait for `Sheep`. +impl Animal for Sheep { + // `Self` is the implementor type: `Sheep`. + fn new(name: &'static str) -> Sheep { + Sheep { name: name, naked: false } + } + + fn name(&self) -> &'static str { + self.name + } + + fn noise(&self) -> &'static str { + if self.is_naked() { + "baaaaah?" + } else { + "baaaaah!" + } + } + + // Default trait methods can be overridden. + fn talk(&self) { + // For example, we can add some quiet contemplation. + println!("{} pauses briefly... {}", self.name, self.noise()); + } +} + +fn main() { + // Type annotation is necessary in this case. + let mut dolly: Sheep = Animal::new("Dolly"); + // TODO ^ Try removing the type annotations. + + dolly.talk(); + dolly.shear(); + dolly.talk(); +} +``` \ No newline at end of file diff --git a/src/trait/clone.md b/src/trait/clone.md index 2e497b48e4..acd531632a 100644 --- a/src/trait/clone.md +++ b/src/trait/clone.md @@ -1 +1,55 @@ # Clone + +When dealing with resources, the default behavior is to transfer them during +assignments or function calls. However, sometimes we need to make a +copy of the resource as well. + +The [`Clone`][clone] trait helps us do exactly this. Most commonly, we can +use the `.clone()` method defined by the `Clone` trait. + +```rust,editable +// A unit struct without resources +#[derive(Debug, Clone, Copy)] +struct Nil; + +// A tuple struct with resources that implements the `Clone` trait +#[derive(Clone, Debug)] +struct Pair(Box, Box); + +fn main() { + // Instantiate `Nil` + let nil = Nil; + // Copy `Nil`, there are no resources to move + let copied_nil = nil; + + // Both `Nil`s can be used independently + println!("original: {:?}", nil); + println!("copy: {:?}", copied_nil); + + // Instantiate `Pair` + let pair = Pair(Box::new(1), Box::new(2)); + println!("original: {:?}", pair); + + // Copy `pair` into `moved_pair`, moves resources + let moved_pair = pair; + println!("copy: {:?}", moved_pair); + + // Error! `pair` has lost its resources + //println!("original: {:?}", pair); + // TODO ^ Try uncommenting this line + + // Clone `moved_pair` into `cloned_pair` (resources are included) + let cloned_pair = moved_pair.clone(); + // Drop the original pair using std::mem::drop + drop(moved_pair); + + // Error! `moved_pair` has been dropped + //println!("copy: {:?}", moved_pair); + // TODO ^ Try uncommenting this line + + // The result from .clone() can still be used! + println!("clone: {:?}", cloned_pair); +} +``` + +[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html \ No newline at end of file diff --git a/src/trait/derive.md b/src/trait/derive.md index f12a0658d3..b254e3c896 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -1 +1,78 @@ # Derive + +The compiler is capable of providing basic implementations for some traits via +the `#[derive]` [attribute][attribute]. These traits can still be +manually implemented if a more complex behavior is required. + +The following is a list of derivable traits: +* Comparison traits: + [`Eq`][eq], [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord] +* [`Clone`][clone], to create `T` from `&T` via a copy. +* [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics' +* [`Hash`][hash], to compute a hash from `&T`. +* [`Default`][default], to create an empty instance of a data type. +* `Zero`, to create a zero instance of a numeric data type. +* [`Debug`][debug], to format a value using the `{:?}` formatter. + +```rust,example +// `Centimeters`, a tuple struct that can be compared +#[derive(PartialEq, PartialOrd)] +struct Centimeters(f64); + +// `Inches`, a tuple struct that can be printed +#[derive(Debug)] +struct Inches(i32); + +impl Inches { + fn to_centimeters(&self) -> Centimeters { + let &Inches(inches) = self; + + Centimeters(inches as f64 * 2.54) + } +} + +// `Seconds`, a tuple struct no additional attributes +struct Seconds(i32); + +fn main() { + let _one_second = Seconds(1); + + // Error: `Seconds` can't be printed; it doesn't implement the `Debug` trait + //println!("One second looks like: {:?}", _one_second); + // TODO ^ Try uncommenting this line + + // Error: `Seconds` can't be compared; it doesn't implement the `PartialEq` trait + //let _this_is_true = (_one_second == _one_second); + // TODO ^ Try uncommenting this line + + let foot = Inches(12); + + println!("One foot equals {:?}", foot); + + let meter = Centimeters(100.0); + + let cmp = + if foot.to_centimeters() < meter { + "smaller" + } else { + "bigger" + }; + + println!("One foot is {} than one meter.", cmp); +} +``` + +### See also: +[`derive`][derive] + +[attribute]: /attribute.html +[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html +[partial-eq]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html +[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html +[partial-ord]: https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html +[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html +[copy]: https://doc.rust-lang.org/core/marker/trait.Copy.html +[hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html +[default]: https://doc.rust-lang.org/std/default/trait.Default.html +[debug]: https://doc.rust-lang.org/std/fmt/trait.Debug.html +[derive]: https://doc.rust-lang.org/reference/attributes.html#derive diff --git a/src/trait/drop.md b/src/trait/drop.md index c6ecf823e5..7aeaca7173 100644 --- a/src/trait/drop.md +++ b/src/trait/drop.md @@ -1 +1,57 @@ # Drop + +The [`Drop`][Drop] trait only has one method: `drop`, which is called automatically +when an object goes out of scope. The main use of the `Drop` trait is to free the +resources that the implementor instance owns. + +`Box`, `Vec`, `String`, `File`, and `Process` are some examples of types that +implement the `Drop` trait to free resources. The `Drop` trait can also be +manually implemented for any custom data type. + +The following example adds a print to console to the `drop` function to announce +when it is called. + +```rust,editable +struct Droppable { + name: &'static str, +} + +// This trivial implementation of `drop` adds a print to console. +impl Drop for Droppable { + fn drop(&mut self) { + println!("> Dropping {}", self.name); + } +} + +fn main() { + let _a = Droppable { name: "a" }; + + // block A + { + let _b = Droppable { name: "b" }; + + // block B + { + let _c = Droppable { name: "c" }; + let _d = Droppable { name: "d" }; + + println!("Exiting block B"); + } + println!("Just exited block B"); + + println!("Exiting block A"); + } + println!("Just exited block A"); + + // Variable can be manually dropped using the `drop` function + drop(_a); + // TODO ^ Try commenting this line + + println!("end of the main function"); + + // `_a` *won't* be `drop`ed again here, because it already has been + // (manually) `drop`ed +} +``` + +[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html \ No newline at end of file diff --git a/src/trait/iter.md b/src/trait/iter.md index 7f511b9862..11758aec3b 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -1 +1,87 @@ # Iterators + +The `Iterator` trait is used to implement iterators over collections such as arrays. + +The trait requires only a method to be defined for the `next` element, +which may be manually defined in an `impl` block or automatically +defined (as in arrays and ranges). + +As a point of convenience for common situations, the `for` construct +turns some collections into iterators using the [`.into_iterator()`][intoiter] method. + +Methods that can be accessed using the `Iterator` trait in addition +to those shown in the example below can be found [here][iter]. + +```rust,editable +struct Fibonacci { + curr: u32, + next: u32, +} + +// Implement `Iterator` for `Fibonacci`. +// The `Iterator` trait only requires a method to be defined for the `next` element. +impl Iterator for Fibonacci { + type Item = u32; + + // Here, we define the sequence using `.curr` and `.next`. + // The return type is `Option`: + // * When the `Iterator` is finished, `None` is returned. + // * Otherwise, the next value is wrapped in `Some` and returned. + fn next(&mut self) -> Option { + let new_next = self.curr + self.next; + + self.curr = self.next; + self.next = new_next; + + // Since there's no endpoint to a Fibonacci sequence, the `Iterator` + // will never return `None`, and `Some` is always returned. + Some(self.curr) + } +} + +// Returns a Fibonacci sequence generator +fn fibonacci() -> Fibonacci { + Fibonacci { curr: 1, next: 1 } +} + +fn main() { + // `0..3` is an `Iterator` that generates: 0, 1, and 2. + let mut sequence = 0..3; + + println!("Four consecutive `next` calls on 0..3"); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); + println!("> {:?}", sequence.next()); + + // `for` works through an `Iterator` until it returns `None`. + // Each `Some` value is unwrapped and bound to a variable (here, `i`). + println!("Iterate through 0..3 using `for`"); + for i in 0..3 { + println!("> {}", i); + } + + // The `take(n)` method reduces an `Iterator` to its first `n` terms. + println!("The first four terms of the Fibonacci sequence are: "); + for i in fibonacci().take(4) { + println!("> {}", i); + } + + // The `skip(n)` method shortens an `Iterator` by dropping its first `n` terms. + println!("The next four terms of the Fibonacci sequence are: "); + for i in fibonacci().skip(4).take(4) { + println!("> {}", i); + } + + let array = [1u32, 3, 3, 7]; + + // The `iter` method produces an `Iterator` over an array/slice. + println!("Iterate the following array {:?}", &array); + for i in array.iter() { + println!("> {}", i); + } +} +``` + +[intoiter]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html +[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/src/trait/ops.md b/src/trait/ops.md index 6917574a31..8d7ff3f97d 100644 --- a/src/trait/ops.md +++ b/src/trait/ops.md @@ -1 +1,61 @@ # Operator Overloading + +In Rust, many of the operators can be overloaded via traits. That is, some operators can +be used to accomplish different tasks based on their input arguments. This is possible +because operators are syntactic sugar for method calls. For example, the `+` operator in +`a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` +trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. + +A list of the traits, such as `Add`, that overload operators is available [here][ops]. + +```rust,editable +use std::ops; + +struct Foo; +struct Bar; + +#[derive(Debug)] +struct FooBar; + +#[derive(Debug)] +struct BarFoo; + +// The `std::ops::Add` trait is used to specify the functionality of `+`. +// Here, we make `Add` - the trait for addition with a RHS of type `Bar`. +// The following block implements the operation: Foo + Bar = FooBar +impl ops::Add for Foo { + type Output = FooBar; + + fn add(self, _rhs: Bar) -> FooBar { + println!("> Foo.add(Bar) was called"); + + FooBar + } +} + +// By reversing the types, we end up implementing non-commutative addition. +// Here, we make `Add` - the trait for addition with a RHS of type `Foo`. +// This block implements the operation: Bar + Foo = BarFoo +impl ops::Add for Bar { + type Output = BarFoo; + + fn add(self, _rhs: Foo) -> BarFoo { + println!("> Bar.add(Foo) was called"); + + BarFoo + } +} + +fn main() { + println!("Foo + Bar = {:?}", Foo + Bar); + println!("Bar + Foo = {:?}", Bar + Foo); +} +``` + +###See Also + +[Add][add], [Syntax Index][syntax] + +[add]: https://doc.rust-lang.org/core/ops/trait.Add.html +[ops]: https://doc.rust-lang.org/core/ops/ +[syntax]: https://doc.rust-lang.org/book/syntax-index.html From 70acf9d8262362b07f0a1efefe1e642850e7db01 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:30:15 -0400 Subject: [PATCH 0646/1122] chapter: std types --- examples/std/box/box.rs | 63 ------------- examples/std/box/input.md | 9 -- .../std/hash/alt_key_types/alt_key_types.rs | 56 ------------ examples/std/hash/alt_key_types/input.md | 30 ------- examples/std/hash/hash.rs | 43 --------- examples/std/hash/hashset/hashset.rs | 36 -------- examples/std/hash/hashset/input.md | 38 -------- examples/std/hash/input.md | 18 ---- examples/std/input.md | 15 ---- examples/std/option/input.md | 9 -- examples/std/option/option.rs | 38 -------- examples/std/panic/input.md | 29 ------ examples/std/panic/panic.rs | 22 ----- examples/std/result/input.md | 13 --- examples/std/result/result.rs | 58 ------------ examples/std/result/try/input.md | 11 --- examples/std/result/try/try.rs | 63 ------------- examples/std/str/input.md | 18 ---- examples/std/str/str.rs | 40 --------- examples/std/vec/input.md | 13 --- examples/std/vec/vec.rs | 30 ------- src/std.md | 16 ++++ src/std/alt_key_types.md | 88 +++++++++++++++++++ src/std/box.md | 74 ++++++++++++++++ src/std/hash.md | 63 +++++++++++++ src/std/hashset.md | 75 ++++++++++++++++ src/std/option.md | 49 +++++++++++ src/std/panic.md | 53 +++++++++++ src/std/result.md | 73 +++++++++++++++ src/std/str.md | 60 +++++++++++++ src/std/try.md | 76 ++++++++++++++++ src/std/vec.md | 45 ++++++++++ 32 files changed, 672 insertions(+), 652 deletions(-) delete mode 100644 examples/std/box/box.rs delete mode 100644 examples/std/box/input.md delete mode 100644 examples/std/hash/alt_key_types/alt_key_types.rs delete mode 100644 examples/std/hash/alt_key_types/input.md delete mode 100644 examples/std/hash/hash.rs delete mode 100644 examples/std/hash/hashset/hashset.rs delete mode 100644 examples/std/hash/hashset/input.md delete mode 100644 examples/std/hash/input.md delete mode 100644 examples/std/input.md delete mode 100644 examples/std/option/input.md delete mode 100644 examples/std/option/option.rs delete mode 100644 examples/std/panic/input.md delete mode 100644 examples/std/panic/panic.rs delete mode 100644 examples/std/result/input.md delete mode 100644 examples/std/result/result.rs delete mode 100644 examples/std/result/try/input.md delete mode 100644 examples/std/result/try/try.rs delete mode 100644 examples/std/str/input.md delete mode 100644 examples/std/str/str.rs delete mode 100644 examples/std/vec/input.md delete mode 100644 examples/std/vec/vec.rs diff --git a/examples/std/box/box.rs b/examples/std/box/box.rs deleted file mode 100644 index 91b380411f..0000000000 --- a/examples/std/box/box.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::mem; - -#[allow(dead_code)] -#[derive(Debug, Clone, Copy)] -struct Point { - x: f64, - y: f64, -} - -#[allow(dead_code)] -struct Rectangle { - p1: Point, - p2: Point, -} - -fn origin() -> Point { - Point { x: 0.0, y: 0.0 } -} - -fn boxed_origin() -> Box { - // Allocate this point in the heap, and return a pointer to it - Box::new(Point { x: 0.0, y: 0.0 }) -} - -fn main() { - // (all the type annotations are superfluous) - // Stack allocated variables - let point: Point = origin(); - let rectangle: Rectangle = Rectangle { - p1: origin(), - p2: Point { x: 3.0, y: 4.0 } - }; - - // Heap allocated rectangle - let boxed_rectangle: Box = Box::new(Rectangle { - p1: origin(), - p2: origin() - }); - - // The output of functions can be boxed - let boxed_point: Box = Box::new(origin()); - - // Double indirection - let box_in_a_box: Box> = Box::new(boxed_origin()); - - println!("Point occupies {} bytes in the stack", - mem::size_of_val(&point)); - println!("Rectangle occupies {} bytes in the stack", - mem::size_of_val(&rectangle)); - - // box size = pointer size - println!("Boxed point occupies {} bytes in the stack", - mem::size_of_val(&boxed_point)); - println!("Boxed rectangle occupies {} bytes in the stack", - mem::size_of_val(&boxed_rectangle)); - println!("Boxed box occupies {} bytes in the stack", - mem::size_of_val(&box_in_a_box)); - - // Copy the data contained in `boxed_point` into `unboxed_point` - let unboxed_point: Point = *boxed_point; - println!("Unboxed point occupies {} bytes in the stack", - mem::size_of_val(&unboxed_point)); -} diff --git a/examples/std/box/input.md b/examples/std/box/input.md deleted file mode 100644 index 9eed38aad0..0000000000 --- a/examples/std/box/input.md +++ /dev/null @@ -1,9 +0,0 @@ -All values in Rust are stack allocated by default. Values can be *boxed* -(allocated in the heap) by creating a `Box`. A box is a smart pointer to a -heap allocated value of type `T`. When a box goes out of scope, its destructor -is called, the inner object is destroyed, and the memory in the heap is freed. - -Boxed values can be dereferenced using the `*` operator; this removes one layer -of indirection. - -{box.play} diff --git a/examples/std/hash/alt_key_types/alt_key_types.rs b/examples/std/hash/alt_key_types/alt_key_types.rs deleted file mode 100644 index 19103b4ba1..0000000000 --- a/examples/std/hash/alt_key_types/alt_key_types.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::collections::HashMap; - -// Eq requires that you derive PartialEq on the type. -#[derive(PartialEq, Eq, Hash)] -struct Account<'a>{ - username: &'a str, - password: &'a str, -} - -struct AccountInfo<'a>{ - name: &'a str, - email: &'a str, -} - -type Accounts<'a> = HashMap, AccountInfo<'a>>; - -fn try_logon<'a>(accounts: &Accounts<'a>, - username: &'a str, password: &'a str){ - println!("Username: {}", username); - println!("Password: {}", password); - println!("Attempting logon..."); - - let logon = Account { - username: username, - password: password, - }; - - match accounts.get(&logon) { - Some(account_info) => { - println!("Successful logon!"); - println!("Name: {}", account_info.name); - println!("Email: {}", account_info.email); - }, - _ => println!("Login failed!"), - } -} - -fn main(){ - let mut accounts: Accounts = HashMap::new(); - - let account = Account { - username: "j.everyman", - password: "password123", - }; - - let account_info = AccountInfo { - name: "John Everyman", - email: "j.everyman@email.com", - }; - - accounts.insert(account, account_info); - - try_logon(&accounts, "j.everyman", "psasword123"); - - try_logon(&accounts, "j.everyman", "password123"); -} diff --git a/examples/std/hash/alt_key_types/input.md b/examples/std/hash/alt_key_types/input.md deleted file mode 100644 index a9f09f348e..0000000000 --- a/examples/std/hash/alt_key_types/input.md +++ /dev/null @@ -1,30 +0,0 @@ -Any type that implements the `Eq` and `Hash` traits can be a key in `HashMap`. -This includes: - -* `bool` (though not very useful since there is only two possible keys) -* `int`, `uint`, and all variations thereof -* `String` and `&str` (protip: you can have a `HashMap` keyed by `String` -and call `.get()` with an `&str`) - -Note that `f32` and `f64` do *not* implement `Hash`, -likely because [floating-point precision errors][floating] -would make using them as hashmap keys horribly error-prone. - -All collection classes implement `Eq` and `Hash` -if their contained type also respectively implements `Eq` and `Hash`. -For example, `Vec` will implement `Hash` if `T` implements `Hash`. - -You can easily implement `Eq` and `Hash` for a custom type with just one line: -`#[derive(PartialEq, Eq, Hash)]` - -The compiler will do the rest. If you want more control over the details, -you can implement `Eq` and/or `Hash` yourself. -This guide will not cover the specifics of implementing `Hash`. - -To play around with using a `struct` in `HashMap`, -let's try making a very simple user logon system: - -{alt_key_types.play} - -[hash]: https://en.wikipedia.org/wiki/Hash_function -[floating]: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems diff --git a/examples/std/hash/hash.rs b/examples/std/hash/hash.rs deleted file mode 100644 index cf4dfe29d1..0000000000 --- a/examples/std/hash/hash.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::collections::HashMap; - -fn call(number: &str) -> &str { - match number { - "798-1364" => "We're sorry, the call cannot be completed as dialed. - Please hang up and try again.", - "645-7689" => "Hello, this is Mr. Awesome's Pizza. My name is Fred. - What can I get for you today?", - _ => "Hi! Who is this again?" - } -} - -fn main() { - let mut contacts = HashMap::new(); - - contacts.insert("Daniel", "798-1364"); - contacts.insert("Ashley", "645-7689"); - contacts.insert("Katie", "435-8291"); - contacts.insert("Robert", "956-1745"); - - // Takes a reference and returns Option<&V> - match contacts.get(&"Daniel") { - Some(&number) => println!("Calling Daniel: {}", call(number)), - _ => println!("Don't have Daniel's number."), - } - - // `HashMap::insert()` returns `None` - // if the inserted value is new, `Some(value)` otherwise - contacts.insert("Daniel", "164-6743"); - - match contacts.get(&"Ashley") { - Some(&number) => println!("Calling Ashley: {}", call(number)), - _ => println!("Don't have Ashley's number."), - } - - contacts.remove(&("Ashley")); - - // `HashMap::iter()` returns an iterator that yields - // (&'a key, &'a value) pairs in arbitrary order. - for (contact, &number) in contacts.iter() { - println!("Calling {}: {}", contact, call(number)); - } -} diff --git a/examples/std/hash/hashset/hashset.rs b/examples/std/hash/hashset/hashset.rs deleted file mode 100644 index a5f9b02821..0000000000 --- a/examples/std/hash/hashset/hashset.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::collections::HashSet; - -fn main() { - let mut a: HashSet = vec!(1i32, 2, 3).into_iter().collect(); - let mut b: HashSet = vec!(2i32, 3, 4).into_iter().collect(); - - assert!(a.insert(4)); - assert!(a.contains(&4)); - - // `HashSet::insert()` returns false if - // there was a value already present. - assert!(b.insert(4), "Value 4 is already in set B!"); - // FIXME ^ Comment out this line - - b.insert(5); - - // If a collection's element type implements `Debug`, - // then the collection implements `Debug`. - // It usually prints its elements in the format `[elem1, elem2, ...]` - println!("A: {:?}", a); - println!("B: {:?}", b); - - // Print [1, 2, 3, 4, 5] in arbitrary order - println!("Union: {:?}", a.union(&b).collect::>()); - - // This should print [1] - println!("Difference: {:?}", a.difference(&b).collect::>()); - - // Print [2, 3, 4] in arbitrary order. - println!("Intersection: {:?}", a.intersection(&b).collect::>()); - - // Print [1, 5] - println!("Symmetric Difference: {:?}", - a.symmetric_difference(&b).collect::>()); -} - diff --git a/examples/std/hash/hashset/input.md b/examples/std/hash/hashset/input.md deleted file mode 100644 index 575d99ec1f..0000000000 --- a/examples/std/hash/hashset/input.md +++ /dev/null @@ -1,38 +0,0 @@ -Consider a `HashSet` as a `HashMap` where we just care about the keys ( -`HashSet` is, in actuality, just a wrapper around `HashMap`). - -"What's the point of that?" you ask. "I could just store the keys in a `Vec`." - -A `HashSet`'s unique feature is that -it is guaranteed to not have duplicate elements. -That's the contract that any set collection fulfills. -`HashSet` is just one implementation. (see also: [`BTreeSet`][treeset]) - -If you insert a value that is already present in the `HashSet`, -(i.e. the new value is equal to the existing and they both have the same hash), -then the new value will replace the old. - -This is great for when you never want more than one of something, -or when you want to know if you've already got something. - -But sets can do more than that. - -Sets have 4 primary operations (all of the following calls return an iterator): - -* `union`: get all the unique elements in both sets. - -* `difference`: get all the elements that are in the first set but not the second. - -* `intersection`: get all the elements that are only in *both* sets. - -* `symmetric_difference`: -get all the elements that are in one set or the other, but *not* both. - -Try all of these in the following example. - -{hashset.play} - -(Examples adapted from the [documentation.][hash-set]) - -[treeset]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html -[hash-set]: https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference diff --git a/examples/std/hash/input.md b/examples/std/hash/input.md deleted file mode 100644 index 6f44ec1ef2..0000000000 --- a/examples/std/hash/input.md +++ /dev/null @@ -1,18 +0,0 @@ -Where vectors store values by an integer index, `HashMap`s store values by key. -`HashMap` keys can be booleans, integers, strings, -or any other type that implements the `Eq` and `Hash` traits. -More on this in the next section. - -Like vectors, `HashMap`s are growable, but HashMaps can also shrink themselves -when they have excess space. -You can create a HashMap with a certain starting capacity using -`HashMap::with_capacity(uint)`, or use `HashMap::new()` to get a HashMap -with a default initial capacity (recommended). - -{hash.play} - -For more information on how hashing and hash maps -(sometimes called hash tables) work, have a look at -[Hash Table Wikipedia][wiki-hash] - -[wiki-hash]: https://en.wikipedia.org/wiki/Hash_table diff --git a/examples/std/input.md b/examples/std/input.md deleted file mode 100644 index edffc3e5fa..0000000000 --- a/examples/std/input.md +++ /dev/null @@ -1,15 +0,0 @@ -The `std` library provides many custom types which expands drastically on -the `primitives`. Some of these include: - -* growable `String`s like: `"hello world"` -* growable vectors: `[1, 2, 3]` -* optional types: `Option` -* error handling types: `Result` -* heap allocated pointers: `Box` - -### See also: - -[primitives][primitives] and [the std library][std] - -[primitives]: /primitives.html -[std]: https://doc.rust-lang.org/std/ diff --git a/examples/std/option/input.md b/examples/std/option/input.md deleted file mode 100644 index 94365e77a0..0000000000 --- a/examples/std/option/input.md +++ /dev/null @@ -1,9 +0,0 @@ -Sometimes it's desirable to catch the failure of some parts of a program -instead of calling `panic!`; this can be accomplished using the `Option` enum. - -The `Option` enum has two variants: - -* `None`, to indicate failure or lack of value, and -* `Some(value)`, a tuple struct that wraps a `value` with type `T`. - -{option.play} diff --git a/examples/std/option/option.rs b/examples/std/option/option.rs deleted file mode 100644 index e2cc8aec9d..0000000000 --- a/examples/std/option/option.rs +++ /dev/null @@ -1,38 +0,0 @@ -// An integer division that doesn't `panic!` -fn checked_division(dividend: i32, divisor: i32) -> Option { - if divisor == 0 { - // Failure is represented as the `None` variant - None - } else { - // Result is wrapped in a `Some` variant - Some(dividend / divisor) - } -} - -// This function handles a division that may not succeed -fn try_division(dividend: i32, divisor: i32) { - // `Option` values can be pattern matched, just like other enums - match checked_division(dividend, divisor) { - None => println!("{} / {} failed!", dividend, divisor), - Some(quotient) => { - println!("{} / {} = {}", dividend, divisor, quotient) - }, - } -} - -fn main() { - try_division(4, 2); - try_division(1, 0); - - // Binding `None` to a variable needs to be type annotated - let none: Option = None; - let _equivalent_none = None::; - - let optional_float = Some(0f32); - - // Unwrapping a `Some` variant will extract the value wrapped. - println!("{:?} unwraps to {:?}", optional_float, optional_float.unwrap()); - - // Unwrapping a `None` variant will `panic!` - println!("{:?} unwraps to {:?}", none, none.unwrap()); -} diff --git a/examples/std/panic/input.md b/examples/std/panic/input.md deleted file mode 100644 index a9f91b6321..0000000000 --- a/examples/std/panic/input.md +++ /dev/null @@ -1,29 +0,0 @@ -The `panic!` macro can be used to generate a panic and start unwinding -its stack. While unwinding, the runtime will take care of freeing all the -resources *owned* by the thread by calling the destructor of all its objects. - -Since we are dealing with programs with only one thread, `panic!` will cause the -program to report the panic message and exit. - -{panic.play} - -Let's check that `panic!` doesn't leak memory. - -``` -$ rustc panic.rs && valgrind ./panic -==4401== Memcheck, a memory error detector -==4401== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. -==4401== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info -==4401== Command: ./panic -==4401== -thread '

' panicked at 'division by zero', panic.rs:5 -==4401== -==4401== HEAP SUMMARY: -==4401== in use at exit: 0 bytes in 0 blocks -==4401== total heap usage: 18 allocs, 18 frees, 1,648 bytes allocated -==4401== -==4401== All heap blocks were freed -- no leaks are possible -==4401== -==4401== For counts of detected and suppressed errors, rerun with: -v -==4401== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -``` diff --git a/examples/std/panic/panic.rs b/examples/std/panic/panic.rs deleted file mode 100644 index b386dc82e7..0000000000 --- a/examples/std/panic/panic.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Re-implementation of integer division (/) -fn division(dividend: i32, divisor: i32) -> i32 { - if divisor == 0 { - // Division by zero triggers a panic - panic!("division by zero"); - } else { - dividend / divisor - } -} - -// The `main` task -fn main() { - // Heap allocated integer - let _x = Box::new(0i32); - - // This operation will trigger a task failure - division(3, 0); - - println!("This point won't be reached!"); - - // `_x` should get destroyed at this point -} diff --git a/examples/std/result/input.md b/examples/std/result/input.md deleted file mode 100644 index 355af9334a..0000000000 --- a/examples/std/result/input.md +++ /dev/null @@ -1,13 +0,0 @@ -We've seen that the `Option` enum can be used as a return value from functions -that may fail, where `None` can be returned to indicate failure. However, -sometimes it is important to express *why* an operation failed. To do this we -have the `Result` enum. - -The `Result` enum has two variants: - -* `Ok(value)` which indicates that the operation succeeded, and wraps the - `value` returned by the operation. (`value` has type `T`) -* `Err(why)`, which indicates that the operation failed, and wraps `why`, - which (hopefully) explains the cause of the failure. (`why` has type `E`) - -{result.play} diff --git a/examples/std/result/result.rs b/examples/std/result/result.rs deleted file mode 100644 index f84611f5b2..0000000000 --- a/examples/std/result/result.rs +++ /dev/null @@ -1,58 +0,0 @@ -mod checked { - // Mathematical "errors" we want to catch - #[derive(Debug)] - pub enum MathError { - DivisionByZero, - NonPositiveLogarithm, - NegativeSquareRoot, - } - - pub type MathResult = Result; - - pub fn div(x: f64, y: f64) -> MathResult { - if y == 0.0 { - // This operation would `fail`, instead let's return the reason of - // the failure wrapped in `Err` - Err(MathError::DivisionByZero) - } else { - // This operation is valid, return the result wrapped in `Ok` - Ok(x / y) - } - } - - pub fn sqrt(x: f64) -> MathResult { - if x < 0.0 { - Err(MathError::NegativeSquareRoot) - } else { - Ok(x.sqrt()) - } - } - - pub fn ln(x: f64) -> MathResult { - if x <= 0.0 { - Err(MathError::NonPositiveLogarithm) - } else { - Ok(x.ln()) - } - } -} - -// `op(x, y)` === `sqrt(ln(x / y))` -fn op(x: f64, y: f64) -> f64 { - // This is a three level match pyramid! - match checked::div(x, y) { - Err(why) => panic!("{:?}", why), - Ok(ratio) => match checked::ln(ratio) { - Err(why) => panic!("{:?}", why), - Ok(ln) => match checked::sqrt(ln) { - Err(why) => panic!("{:?}", why), - Ok(sqrt) => sqrt, - }, - }, - } -} - -fn main() { - // Will this fail? - println!("{}", op(1.0, 10.0)); -} diff --git a/examples/std/result/try/input.md b/examples/std/result/try/input.md deleted file mode 100644 index 909fe86d99..0000000000 --- a/examples/std/result/try/input.md +++ /dev/null @@ -1,11 +0,0 @@ -Chaining results using match can get pretty untidy; luckily, the `try!` macro -can be used to make things pretty again. The `try!` macro expands to a match -expression, where the `Err(err)` branch expands to an early `return Err(err)`, -and the `Ok(ok)` branch expands to an `ok` expression. - -{try.play} - -Be sure to check the [documentation][docs], -as there are many methods to map/compose `Result`. - -[docs]: https://doc.rust-lang.org/std/result/index.html diff --git a/examples/std/result/try/try.rs b/examples/std/result/try/try.rs deleted file mode 100644 index c7242dac41..0000000000 --- a/examples/std/result/try/try.rs +++ /dev/null @@ -1,63 +0,0 @@ -mod checked { - #[derive(Debug)] - enum MathError { - DivisionByZero, - NonPositiveLogarithm, - NegativeSquareRoot, - } - - type MathResult = Result; - - fn div(x: f64, y: f64) -> MathResult { - if y == 0.0 { - Err(MathError::DivisionByZero) - } else { - Ok(x / y) - } - } - - fn sqrt(x: f64) -> MathResult { - if x < 0.0 { - Err(MathError::NegativeSquareRoot) - } else { - Ok(x.sqrt()) - } - } - - fn ln(x: f64) -> MathResult { - if x <= 0.0 { - Err(MathError::NonPositiveLogarithm) - } else { - Ok(x.ln()) - } - } - - // Intermediate function - fn op_(x: f64, y: f64) -> MathResult { - // if `div` "fails", then `DivisionByZero` will be `return`ed - let ratio = try!(div(x, y)); - - // if `ln` "fails", then `NegativeLogarithm` will be `return`ed - let ln = try!(ln(ratio)); - - sqrt(ln) - } - - pub fn op(x: f64, y: f64) { - match op_(x, y) { - Err(why) => panic!(match why { - MathError::NonPositiveLogarithm - => "logarithm of non-positive number", - MathError::DivisionByZero - => "division by zero", - MathError::NegativeSquareRoot - => "square root of negative number", - }), - Ok(value) => println!("{}", value), - } - } -} - -fn main() { - checked::op(1.0, 10.0); -} diff --git a/examples/std/str/input.md b/examples/std/str/input.md deleted file mode 100644 index 2cee4f0568..0000000000 --- a/examples/std/str/input.md +++ /dev/null @@ -1,18 +0,0 @@ -There are two types of strings in Rust: `String` and `&str`. - -A `String` is stored as a vector of bytes (`Vec`), but guaranteed to -always be a valid UTF-8 sequence. `String` is heap allocated, growable and not -null terminated. - -`&str` is a slice (`&[u8]`) that always points to a valid UTF-8 sequence, and -can be used to view into a `String`, just like `&[T]` is a view into `Vec`. - -{str.play} - -More `str`/`String` methods can be found under the -[std::str][str] and -[std::string][string] -modules - -[str]: https://doc.rust-lang.org/std/str/ -[string]: https://doc.rust-lang.org/std/string/ diff --git a/examples/std/str/str.rs b/examples/std/str/str.rs deleted file mode 100644 index 7b88acb5bc..0000000000 --- a/examples/std/str/str.rs +++ /dev/null @@ -1,40 +0,0 @@ -fn main() { - // (all the type annotations are superfluous) - // A reference to a string allocated in read only memory - let pangram: &'static str = "the quick brown fox jumps over the lazy dog"; - println!("Pangram: {}", pangram); - - // Iterate over words in reverse, no new string is allocated - println!("Words in reverse"); - for word in pangram.split_whitespace().rev() { - println!("> {}", word); - } - - // Copy chars into a vector, sort and remove duplicates - let mut chars: Vec = pangram.chars().collect(); - chars.sort(); - chars.dedup(); - - // Create an empty and growable `String` - let mut string = String::new(); - for c in chars { - // Insert a char at the end of string - string.push(c); - // Insert a string at the end of string - string.push_str(", "); - } - - // The trimmed string is a slice to the original string, hence no new - // allocation is performed - let chars_to_trim: &[char] = &[' ', ',']; - let trimmed_str: &str = string.trim_matches(chars_to_trim); - println!("Used characters: {}", trimmed_str); - - // Heap allocate a string - let alice = String::from("I like dogs"); - // Allocate new memory and store the modified string there - let bob: String = alice.replace("dog", "cat"); - - println!("Alice says: {}", alice); - println!("Bob says: {}", bob); -} diff --git a/examples/std/vec/input.md b/examples/std/vec/input.md deleted file mode 100644 index f5a7f71bcf..0000000000 --- a/examples/std/vec/input.md +++ /dev/null @@ -1,13 +0,0 @@ -Vectors are re-sizable arrays. Like slices, their size is not known at compile -time, but they can grow or shrink at any time. A vector is represented using -3 words: a pointer to the data, its length, and its capacity. The capacity -indicates how much memory is reserved for the vector. The vector can grow as -long as the length is smaller than the capacity. When this threshold needs to -be surpassed, the vector is reallocated with a larger capacity. - -{vec.play} - -More `Vec` methods can be found under the -[std::vec][vec] module - -[vec]: https://doc.rust-lang.org/std/vec/ diff --git a/examples/std/vec/vec.rs b/examples/std/vec/vec.rs deleted file mode 100644 index afb6d7a8c9..0000000000 --- a/examples/std/vec/vec.rs +++ /dev/null @@ -1,30 +0,0 @@ -fn main() { - // Iterators can be collected into vectors - let collected_iterator: Vec = (0..10).collect(); - println!("Collected (0..10) into: {:?}", collected_iterator); - - // The `vec!` macro can be used to initialize a vector - let mut xs = vec![1i32, 2, 3]; - println!("Initial vector: {:?}", xs); - - // Insert new element at the end of the vector - println!("Push 4 into the vector"); - xs.push(4); - println!("Vector: {:?}", xs); - - // Error! Immutable vectors can't grow - collected_iterator.push(0); - // FIXME ^ Comment out this line - - // The `len` method yields the current size of the vector - println!("Vector size: {}", xs.len()); - - // Indexing is done using the square brackets (indexing starts at 0) - println!("Second element: {}", xs[1]); - - // `pop` removes the last element from the vector and returns it - println!("Pop last element: {:?}", xs.pop()); - - // Out of bounds indexing yields a panic - println!("Fourth element: {}", xs[3]); -} diff --git a/src/std.md b/src/std.md index eab248588e..cea4704d82 100644 --- a/src/std.md +++ b/src/std.md @@ -1 +1,17 @@ # Std library types + +The `std` library provides many custom types which expands drastically on +the `primitives`. Some of these include: + +* growable `String`s like: `"hello world"` +* growable vectors: `[1, 2, 3]` +* optional types: `Option` +* error handling types: `Result` +* heap allocated pointers: `Box` + +### See also: + +[primitives][primitives] and [the std library][std] + +[primitives]: /primitives.html +[std]: https://doc.rust-lang.org/std/ diff --git a/src/std/alt_key_types.md b/src/std/alt_key_types.md index d83236cd0d..8b91a13277 100644 --- a/src/std/alt_key_types.md +++ b/src/std/alt_key_types.md @@ -1 +1,89 @@ # Alternate/custom key types + +Any type that implements the `Eq` and `Hash` traits can be a key in `HashMap`. +This includes: + +* `bool` (though not very useful since there is only two possible keys) +* `int`, `uint`, and all variations thereof +* `String` and `&str` (protip: you can have a `HashMap` keyed by `String` +and call `.get()` with an `&str`) + +Note that `f32` and `f64` do *not* implement `Hash`, +likely because [floating-point precision errors][floating] +would make using them as hashmap keys horribly error-prone. + +All collection classes implement `Eq` and `Hash` +if their contained type also respectively implements `Eq` and `Hash`. +For example, `Vec` will implement `Hash` if `T` implements `Hash`. + +You can easily implement `Eq` and `Hash` for a custom type with just one line: +`#[derive(PartialEq, Eq, Hash)]` + +The compiler will do the rest. If you want more control over the details, +you can implement `Eq` and/or `Hash` yourself. +This guide will not cover the specifics of implementing `Hash`. + +To play around with using a `struct` in `HashMap`, +let's try making a very simple user logon system: + +```rust,editable +use std::collections::HashMap; + +// Eq requires that you derive PartialEq on the type. +#[derive(PartialEq, Eq, Hash)] +struct Account<'a>{ + username: &'a str, + password: &'a str, +} + +struct AccountInfo<'a>{ + name: &'a str, + email: &'a str, +} + +type Accounts<'a> = HashMap, AccountInfo<'a>>; + +fn try_logon<'a>(accounts: &Accounts<'a>, + username: &'a str, password: &'a str){ + println!("Username: {}", username); + println!("Password: {}", password); + println!("Attempting logon..."); + + let logon = Account { + username: username, + password: password, + }; + + match accounts.get(&logon) { + Some(account_info) => { + println!("Successful logon!"); + println!("Name: {}", account_info.name); + println!("Email: {}", account_info.email); + }, + _ => println!("Login failed!"), + } +} + +fn main(){ + let mut accounts: Accounts = HashMap::new(); + + let account = Account { + username: "j.everyman", + password: "password123", + }; + + let account_info = AccountInfo { + name: "John Everyman", + email: "j.everyman@email.com", + }; + + accounts.insert(account, account_info); + + try_logon(&accounts, "j.everyman", "psasword123"); + + try_logon(&accounts, "j.everyman", "password123"); +} +``` + +[hash]: https://en.wikipedia.org/wiki/Hash_function +[floating]: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems diff --git a/src/std/box.md b/src/std/box.md index 5076dc2795..64856d7aa7 100644 --- a/src/std/box.md +++ b/src/std/box.md @@ -1 +1,75 @@ # Box, stack and heap + +All values in Rust are stack allocated by default. Values can be *boxed* +(allocated in the heap) by creating a `Box`. A box is a smart pointer to a +heap allocated value of type `T`. When a box goes out of scope, its destructor +is called, the inner object is destroyed, and the memory in the heap is freed. + +Boxed values can be dereferenced using the `*` operator; this removes one layer +of indirection. + +```rust,editable +use std::mem; + +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +struct Point { + x: f64, + y: f64, +} + +#[allow(dead_code)] +struct Rectangle { + p1: Point, + p2: Point, +} + +fn origin() -> Point { + Point { x: 0.0, y: 0.0 } +} + +fn boxed_origin() -> Box { + // Allocate this point in the heap, and return a pointer to it + Box::new(Point { x: 0.0, y: 0.0 }) +} + +fn main() { + // (all the type annotations are superfluous) + // Stack allocated variables + let point: Point = origin(); + let rectangle: Rectangle = Rectangle { + p1: origin(), + p2: Point { x: 3.0, y: 4.0 } + }; + + // Heap allocated rectangle + let boxed_rectangle: Box = Box::new(Rectangle { + p1: origin(), + p2: origin() + }); + + // The output of functions can be boxed + let boxed_point: Box = Box::new(origin()); + + // Double indirection + let box_in_a_box: Box> = Box::new(boxed_origin()); + + println!("Point occupies {} bytes in the stack", + mem::size_of_val(&point)); + println!("Rectangle occupies {} bytes in the stack", + mem::size_of_val(&rectangle)); + + // box size = pointer size + println!("Boxed point occupies {} bytes in the stack", + mem::size_of_val(&boxed_point)); + println!("Boxed rectangle occupies {} bytes in the stack", + mem::size_of_val(&boxed_rectangle)); + println!("Boxed box occupies {} bytes in the stack", + mem::size_of_val(&box_in_a_box)); + + // Copy the data contained in `boxed_point` into `unboxed_point` + let unboxed_point: Point = *boxed_point; + println!("Unboxed point occupies {} bytes in the stack", + mem::size_of_val(&unboxed_point)); +} +``` \ No newline at end of file diff --git a/src/std/hash.md b/src/std/hash.md index 96e549de56..7b736815c2 100644 --- a/src/std/hash.md +++ b/src/std/hash.md @@ -1 +1,64 @@ # HashMap + +Where vectors store values by an integer index, `HashMap`s store values by key. +`HashMap` keys can be booleans, integers, strings, +or any other type that implements the `Eq` and `Hash` traits. +More on this in the next section. + +Like vectors, `HashMap`s are growable, but HashMaps can also shrink themselves +when they have excess space. +You can create a HashMap with a certain starting capacity using +`HashMap::with_capacity(uint)`, or use `HashMap::new()` to get a HashMap +with a default initial capacity (recommended). + +```rust,editable +use std::collections::HashMap; + +fn call(number: &str) -> &str { + match number { + "798-1364" => "We're sorry, the call cannot be completed as dialed. + Please hang up and try again.", + "645-7689" => "Hello, this is Mr. Awesome's Pizza. My name is Fred. + What can I get for you today?", + _ => "Hi! Who is this again?" + } +} + +fn main() { + let mut contacts = HashMap::new(); + + contacts.insert("Daniel", "798-1364"); + contacts.insert("Ashley", "645-7689"); + contacts.insert("Katie", "435-8291"); + contacts.insert("Robert", "956-1745"); + + // Takes a reference and returns Option<&V> + match contacts.get(&"Daniel") { + Some(&number) => println!("Calling Daniel: {}", call(number)), + _ => println!("Don't have Daniel's number."), + } + + // `HashMap::insert()` returns `None` + // if the inserted value is new, `Some(value)` otherwise + contacts.insert("Daniel", "164-6743"); + + match contacts.get(&"Ashley") { + Some(&number) => println!("Calling Ashley: {}", call(number)), + _ => println!("Don't have Ashley's number."), + } + + contacts.remove(&("Ashley")); + + // `HashMap::iter()` returns an iterator that yields + // (&'a key, &'a value) pairs in arbitrary order. + for (contact, &number) in contacts.iter() { + println!("Calling {}: {}", contact, call(number)); + } +} +``` + +For more information on how hashing and hash maps +(sometimes called hash tables) work, have a look at +[Hash Table Wikipedia][wiki-hash] + +[wiki-hash]: https://en.wikipedia.org/wiki/Hash_table diff --git a/src/std/hashset.md b/src/std/hashset.md index 3a3bcd06d5..fbf6197590 100644 --- a/src/std/hashset.md +++ b/src/std/hashset.md @@ -1 +1,76 @@ # HashSet + +Consider a `HashSet` as a `HashMap` where we just care about the keys ( +`HashSet` is, in actuality, just a wrapper around `HashMap`). + +"What's the point of that?" you ask. "I could just store the keys in a `Vec`." + +A `HashSet`'s unique feature is that +it is guaranteed to not have duplicate elements. +That's the contract that any set collection fulfills. +`HashSet` is just one implementation. (see also: [`BTreeSet`][treeset]) + +If you insert a value that is already present in the `HashSet`, +(i.e. the new value is equal to the existing and they both have the same hash), +then the new value will replace the old. + +This is great for when you never want more than one of something, +or when you want to know if you've already got something. + +But sets can do more than that. + +Sets have 4 primary operations (all of the following calls return an iterator): + +* `union`: get all the unique elements in both sets. + +* `difference`: get all the elements that are in the first set but not the second. + +* `intersection`: get all the elements that are only in *both* sets. + +* `symmetric_difference`: +get all the elements that are in one set or the other, but *not* both. + +Try all of these in the following example. + +```rust,editable +use std::collections::HashSet; + +fn main() { + let mut a: HashSet = vec!(1i32, 2, 3).into_iter().collect(); + let mut b: HashSet = vec!(2i32, 3, 4).into_iter().collect(); + + assert!(a.insert(4)); + assert!(a.contains(&4)); + + // `HashSet::insert()` returns false if + // there was a value already present. + assert!(b.insert(4), "Value 4 is already in set B!"); + // FIXME ^ Comment out this line + + b.insert(5); + + // If a collection's element type implements `Debug`, + // then the collection implements `Debug`. + // It usually prints its elements in the format `[elem1, elem2, ...]` + println!("A: {:?}", a); + println!("B: {:?}", b); + + // Print [1, 2, 3, 4, 5] in arbitrary order + println!("Union: {:?}", a.union(&b).collect::>()); + + // This should print [1] + println!("Difference: {:?}", a.difference(&b).collect::>()); + + // Print [2, 3, 4] in arbitrary order. + println!("Intersection: {:?}", a.intersection(&b).collect::>()); + + // Print [1, 5] + println!("Symmetric Difference: {:?}", + a.symmetric_difference(&b).collect::>()); +} +``` + +(Examples adapted from the [documentation.][hash-set]) + +[treeset]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html +[hash-set]: https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference diff --git a/src/std/option.md b/src/std/option.md index b4c6002621..569d4721a8 100644 --- a/src/std/option.md +++ b/src/std/option.md @@ -1 +1,50 @@ # `Option` + +Sometimes it's desirable to catch the failure of some parts of a program +instead of calling `panic!`; this can be accomplished using the `Option` enum. + +The `Option` enum has two variants: + +* `None`, to indicate failure or lack of value, and +* `Some(value)`, a tuple struct that wraps a `value` with type `T`. + +```rust,editable +// An integer division that doesn't `panic!` +fn checked_division(dividend: i32, divisor: i32) -> Option { + if divisor == 0 { + // Failure is represented as the `None` variant + None + } else { + // Result is wrapped in a `Some` variant + Some(dividend / divisor) + } +} + +// This function handles a division that may not succeed +fn try_division(dividend: i32, divisor: i32) { + // `Option` values can be pattern matched, just like other enums + match checked_division(dividend, divisor) { + None => println!("{} / {} failed!", dividend, divisor), + Some(quotient) => { + println!("{} / {} = {}", dividend, divisor, quotient) + }, + } +} + +fn main() { + try_division(4, 2); + try_division(1, 0); + + // Binding `None` to a variable needs to be type annotated + let none: Option = None; + let _equivalent_none = None::; + + let optional_float = Some(0f32); + + // Unwrapping a `Some` variant will extract the value wrapped. + println!("{:?} unwraps to {:?}", optional_float, optional_float.unwrap()); + + // Unwrapping a `None` variant will `panic!` + println!("{:?} unwraps to {:?}", none, none.unwrap()); +} +``` \ No newline at end of file diff --git a/src/std/panic.md b/src/std/panic.md index 82254a157a..6e6d3e61ee 100644 --- a/src/std/panic.md +++ b/src/std/panic.md @@ -1 +1,54 @@ # `panic!` + +The `panic!` macro can be used to generate a panic and start unwinding +its stack. While unwinding, the runtime will take care of freeing all the +resources *owned* by the thread by calling the destructor of all its objects. + +Since we are dealing with programs with only one thread, `panic!` will cause the +program to report the panic message and exit. + +```rust,editable +// Re-implementation of integer division (/) +fn division(dividend: i32, divisor: i32) -> i32 { + if divisor == 0 { + // Division by zero triggers a panic + panic!("division by zero"); + } else { + dividend / divisor + } +} + +// The `main` task +fn main() { + // Heap allocated integer + let _x = Box::new(0i32); + + // This operation will trigger a task failure + division(3, 0); + + println!("This point won't be reached!"); + + // `_x` should get destroyed at this point +} +``` + +Let's check that `panic!` doesn't leak memory. + +```text +$ rustc panic.rs && valgrind ./panic +==4401== Memcheck, a memory error detector +==4401== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==4401== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info +==4401== Command: ./panic +==4401== +thread '
' panicked at 'division by zero', panic.rs:5 +==4401== +==4401== HEAP SUMMARY: +==4401== in use at exit: 0 bytes in 0 blocks +==4401== total heap usage: 18 allocs, 18 frees, 1,648 bytes allocated +==4401== +==4401== All heap blocks were freed -- no leaks are possible +==4401== +==4401== For counts of detected and suppressed errors, rerun with: -v +==4401== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +``` diff --git a/src/std/result.md b/src/std/result.md index 288cf33ef4..37e849c5e2 100644 --- a/src/std/result.md +++ b/src/std/result.md @@ -1 +1,74 @@ # `Result` + +We've seen that the `Option` enum can be used as a return value from functions +that may fail, where `None` can be returned to indicate failure. However, +sometimes it is important to express *why* an operation failed. To do this we +have the `Result` enum. + +The `Result` enum has two variants: + +* `Ok(value)` which indicates that the operation succeeded, and wraps the + `value` returned by the operation. (`value` has type `T`) +* `Err(why)`, which indicates that the operation failed, and wraps `why`, + which (hopefully) explains the cause of the failure. (`why` has type `E`) + +```rust,editable +mod checked { + // Mathematical "errors" we want to catch + #[derive(Debug)] + pub enum MathError { + DivisionByZero, + NonPositiveLogarithm, + NegativeSquareRoot, + } + + pub type MathResult = Result; + + pub fn div(x: f64, y: f64) -> MathResult { + if y == 0.0 { + // This operation would `fail`, instead let's return the reason of + // the failure wrapped in `Err` + Err(MathError::DivisionByZero) + } else { + // This operation is valid, return the result wrapped in `Ok` + Ok(x / y) + } + } + + pub fn sqrt(x: f64) -> MathResult { + if x < 0.0 { + Err(MathError::NegativeSquareRoot) + } else { + Ok(x.sqrt()) + } + } + + pub fn ln(x: f64) -> MathResult { + if x <= 0.0 { + Err(MathError::NonPositiveLogarithm) + } else { + Ok(x.ln()) + } + } +} + +// `op(x, y)` === `sqrt(ln(x / y))` +fn op(x: f64, y: f64) -> f64 { + // This is a three level match pyramid! + match checked::div(x, y) { + Err(why) => panic!("{:?}", why), + Ok(ratio) => match checked::ln(ratio) { + Err(why) => panic!("{:?}", why), + Ok(ln) => match checked::sqrt(ln) { + Err(why) => panic!("{:?}", why), + Ok(sqrt) => sqrt, + }, + }, + } +} + +fn main() { + // Will this fail? + println!("{}", op(1.0, 10.0)); +} +``` \ No newline at end of file diff --git a/src/std/str.md b/src/std/str.md index ed218ce9a0..54261ee602 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -1 +1,61 @@ # Strings + +There are two types of strings in Rust: `String` and `&str`. + +A `String` is stored as a vector of bytes (`Vec`), but guaranteed to +always be a valid UTF-8 sequence. `String` is heap allocated, growable and not +null terminated. + +`&str` is a slice (`&[u8]`) that always points to a valid UTF-8 sequence, and +can be used to view into a `String`, just like `&[T]` is a view into `Vec`. + +```rust,editable +fn main() { + // (all the type annotations are superfluous) + // A reference to a string allocated in read only memory + let pangram: &'static str = "the quick brown fox jumps over the lazy dog"; + println!("Pangram: {}", pangram); + + // Iterate over words in reverse, no new string is allocated + println!("Words in reverse"); + for word in pangram.split_whitespace().rev() { + println!("> {}", word); + } + + // Copy chars into a vector, sort and remove duplicates + let mut chars: Vec = pangram.chars().collect(); + chars.sort(); + chars.dedup(); + + // Create an empty and growable `String` + let mut string = String::new(); + for c in chars { + // Insert a char at the end of string + string.push(c); + // Insert a string at the end of string + string.push_str(", "); + } + + // The trimmed string is a slice to the original string, hence no new + // allocation is performed + let chars_to_trim: &[char] = &[' ', ',']; + let trimmed_str: &str = string.trim_matches(chars_to_trim); + println!("Used characters: {}", trimmed_str); + + // Heap allocate a string + let alice = String::from("I like dogs"); + // Allocate new memory and store the modified string there + let bob: String = alice.replace("dog", "cat"); + + println!("Alice says: {}", alice); + println!("Bob says: {}", bob); +} +``` + +More `str`/`String` methods can be found under the +[std::str][str] and +[std::string][string] +modules + +[str]: https://doc.rust-lang.org/std/str/ +[string]: https://doc.rust-lang.org/std/string/ diff --git a/src/std/try.md b/src/std/try.md index 5db3d1e9e7..d93fed5874 100644 --- a/src/std/try.md +++ b/src/std/try.md @@ -1 +1,77 @@ # `try!` + +Chaining results using match can get pretty untidy; luckily, the `try!` macro +can be used to make things pretty again. The `try!` macro expands to a match +expression, where the `Err(err)` branch expands to an early `return Err(err)`, +and the `Ok(ok)` branch expands to an `ok` expression. + +```rust,editable +mod checked { + #[derive(Debug)] + enum MathError { + DivisionByZero, + NonPositiveLogarithm, + NegativeSquareRoot, + } + + type MathResult = Result; + + fn div(x: f64, y: f64) -> MathResult { + if y == 0.0 { + Err(MathError::DivisionByZero) + } else { + Ok(x / y) + } + } + + fn sqrt(x: f64) -> MathResult { + if x < 0.0 { + Err(MathError::NegativeSquareRoot) + } else { + Ok(x.sqrt()) + } + } + + fn ln(x: f64) -> MathResult { + if x <= 0.0 { + Err(MathError::NonPositiveLogarithm) + } else { + Ok(x.ln()) + } + } + + // Intermediate function + fn op_(x: f64, y: f64) -> MathResult { + // if `div` "fails", then `DivisionByZero` will be `return`ed + let ratio = try!(div(x, y)); + + // if `ln` "fails", then `NegativeLogarithm` will be `return`ed + let ln = try!(ln(ratio)); + + sqrt(ln) + } + + pub fn op(x: f64, y: f64) { + match op_(x, y) { + Err(why) => panic!(match why { + MathError::NonPositiveLogarithm + => "logarithm of non-positive number", + MathError::DivisionByZero + => "division by zero", + MathError::NegativeSquareRoot + => "square root of negative number", + }), + Ok(value) => println!("{}", value), + } + } +} + +fn main() { + checked::op(1.0, 10.0); +} +``` + +Be sure to check the [documentation][docs], +as there are many methods to map/compose `Result`. + +[docs]: https://doc.rust-lang.org/std/result/index.html diff --git a/src/std/vec.md b/src/std/vec.md index 0399265704..3a2ac228c3 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -1 +1,46 @@ # Vectors + +Vectors are re-sizable arrays. Like slices, their size is not known at compile +time, but they can grow or shrink at any time. A vector is represented using +3 words: a pointer to the data, its length, and its capacity. The capacity +indicates how much memory is reserved for the vector. The vector can grow as +long as the length is smaller than the capacity. When this threshold needs to +be surpassed, the vector is reallocated with a larger capacity. + +```rust,editable +fn main() { + // Iterators can be collected into vectors + let collected_iterator: Vec = (0..10).collect(); + println!("Collected (0..10) into: {:?}", collected_iterator); + + // The `vec!` macro can be used to initialize a vector + let mut xs = vec![1i32, 2, 3]; + println!("Initial vector: {:?}", xs); + + // Insert new element at the end of the vector + println!("Push 4 into the vector"); + xs.push(4); + println!("Vector: {:?}", xs); + + // Error! Immutable vectors can't grow + collected_iterator.push(0); + // FIXME ^ Comment out this line + + // The `len` method yields the current size of the vector + println!("Vector size: {}", xs.len()); + + // Indexing is done using the square brackets (indexing starts at 0) + println!("Second element: {}", xs[1]); + + // `pop` removes the last element from the vector and returns it + println!("Pop last element: {:?}", xs.pop()); + + // Out of bounds indexing yields a panic + println!("Fourth element: {}", xs[3]); +} +``` + +More `Vec` methods can be found under the +[std::vec][vec] module + +[vec]: https://doc.rust-lang.org/std/vec/ From eb4ff7aedb44130fd4935d2b33681d82d9021d3e Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:32:09 -0400 Subject: [PATCH 0647/1122] fix up some files in the wrong place --- src/SUMMARY.md | 6 +++--- src/std/{ => hash}/alt_key_types.md | 0 src/std/{ => hash}/hashset.md | 0 src/std/{ => result}/try.md | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/std/{ => hash}/alt_key_types.md (100%) rename src/std/{ => hash}/hashset.md (100%) rename src/std/{ => result}/try.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1b1a1983d2..637ebed971 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -150,11 +150,11 @@ - [Strings](std/str.md) - [`Option`](std/option.md) - [`Result`](std/result.md) - - [`try!`](std/try.md) + - [`try!`](std/result/try.md) - [`panic!`](std/panic.md) - [HashMap](std/hash.md) - - [Alternate/custom key types](std/alt_key_types.md) - - [HashSet](std/hashset.md) + - [Alternate/custom key types](std/hash/alt_key_types.md) + - [HashSet](std/hash/hashset.md) - [Std misc](std_misc.md) - [Threads](std_misc/threads.md) diff --git a/src/std/alt_key_types.md b/src/std/hash/alt_key_types.md similarity index 100% rename from src/std/alt_key_types.md rename to src/std/hash/alt_key_types.md diff --git a/src/std/hashset.md b/src/std/hash/hashset.md similarity index 100% rename from src/std/hashset.md rename to src/std/hash/hashset.md diff --git a/src/std/try.md b/src/std/result/try.md similarity index 100% rename from src/std/try.md rename to src/std/result/try.md From ad4b2cc0031dab8c3d56429d4d15883f3867da23 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:43:37 -0400 Subject: [PATCH 0648/1122] chapter: std misc --- examples/std_misc/arg/args.rs | 13 -- examples/std_misc/arg/input.md | 10 -- examples/std_misc/arg/matching/input.md | 26 --- examples/std_misc/arg/matching/match_args.rs | 65 -------- examples/std_misc/channels/channels.rs | 39 ----- examples/std_misc/channels/input.md | 5 - examples/std_misc/ffi/ffi.rs | 39 ----- examples/std_misc/ffi/input.md | 14 -- examples/std_misc/ffi/safe.rs | 36 ----- examples/std_misc/file/create/create.rs | 35 ---- examples/std_misc/file/create/input.md | 26 --- examples/std_misc/file/input.md | 9 -- examples/std_misc/file/open/input.md | 19 --- examples/std_misc/file/open/open.rs | 29 ---- examples/std_misc/fs/fs.rs | 92 ----------- examples/std_misc/fs/input.md | 40 ----- examples/std_misc/input.md | 15 -- examples/std_misc/path/input.md | 24 --- examples/std_misc/path/path.rs | 19 --- examples/std_misc/process/input.md | 7 - examples/std_misc/process/pipe/input.md | 5 - examples/std_misc/process/pipe/pipe.rs | 41 ----- examples/std_misc/process/process.rs | 19 --- examples/std_misc/process/wait/input.md | 11 -- examples/std_misc/process/wait/wait.rs | 8 - examples/std_misc/threads/input.md | 6 - .../threads/testcase_mapreduce/input.md | 48 ------ .../threads/testcase_mapreduce/mapreduce.rs | 100 ------------ examples/std_misc/threads/threads.rs | 21 --- src/std_misc.md | 16 ++ src/std_misc/arg.md | 25 +++ src/std_misc/arg/matching.md | 93 +++++++++++ src/std_misc/channels.md | 46 ++++++ src/std_misc/ffi.md | 88 ++++++++++ src/std_misc/file.md | 10 ++ src/std_misc/file/create.md | 63 ++++++++ src/std_misc/file/open.md | 51 ++++++ src/std_misc/fs.md | 135 ++++++++++++++++ src/std_misc/path.md | 46 ++++++ src/std_misc/process.md | 28 ++++ src/std_misc/process/pipe.md | 48 ++++++ src/std_misc/process/wait.md | 21 +++ src/std_misc/threads.md | 29 ++++ src/std_misc/threads/testcase_mapreduce.md | 151 ++++++++++++++++++ 44 files changed, 850 insertions(+), 821 deletions(-) delete mode 100644 examples/std_misc/arg/args.rs delete mode 100644 examples/std_misc/arg/input.md delete mode 100644 examples/std_misc/arg/matching/input.md delete mode 100644 examples/std_misc/arg/matching/match_args.rs delete mode 100644 examples/std_misc/channels/channels.rs delete mode 100644 examples/std_misc/channels/input.md delete mode 100644 examples/std_misc/ffi/ffi.rs delete mode 100644 examples/std_misc/ffi/input.md delete mode 100644 examples/std_misc/ffi/safe.rs delete mode 100644 examples/std_misc/file/create/create.rs delete mode 100644 examples/std_misc/file/create/input.md delete mode 100644 examples/std_misc/file/input.md delete mode 100644 examples/std_misc/file/open/input.md delete mode 100644 examples/std_misc/file/open/open.rs delete mode 100644 examples/std_misc/fs/fs.rs delete mode 100644 examples/std_misc/fs/input.md delete mode 100644 examples/std_misc/input.md delete mode 100644 examples/std_misc/path/input.md delete mode 100644 examples/std_misc/path/path.rs delete mode 100644 examples/std_misc/process/input.md delete mode 100644 examples/std_misc/process/pipe/input.md delete mode 100644 examples/std_misc/process/pipe/pipe.rs delete mode 100644 examples/std_misc/process/process.rs delete mode 100644 examples/std_misc/process/wait/input.md delete mode 100644 examples/std_misc/process/wait/wait.rs delete mode 100644 examples/std_misc/threads/input.md delete mode 100644 examples/std_misc/threads/testcase_mapreduce/input.md delete mode 100644 examples/std_misc/threads/testcase_mapreduce/mapreduce.rs delete mode 100644 examples/std_misc/threads/threads.rs diff --git a/examples/std_misc/arg/args.rs b/examples/std_misc/arg/args.rs deleted file mode 100644 index f440abe2ed..0000000000 --- a/examples/std_misc/arg/args.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - - // The first argument is the path that was used to call the program. - println!("My path is {}.", args[0]); - - // The rest of the arguments are the passed command line parameters. - // Call the program like this: - // $ ./args arg1 arg2 - println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]); -} diff --git a/examples/std_misc/arg/input.md b/examples/std_misc/arg/input.md deleted file mode 100644 index 407aa1967c..0000000000 --- a/examples/std_misc/arg/input.md +++ /dev/null @@ -1,10 +0,0 @@ -The command line arguments can be accessed using `std::env::args`, which -returns an iterator that yields a String for each argument: - -{args.play} - -``` -$ ./args 1 2 3 -My path is ./args. -I got 3 arguments: ["1", "2", "3"]. -``` diff --git a/examples/std_misc/arg/matching/input.md b/examples/std_misc/arg/matching/input.md deleted file mode 100644 index 86645aa73e..0000000000 --- a/examples/std_misc/arg/matching/input.md +++ /dev/null @@ -1,26 +0,0 @@ -Matching can be used to parse simple arguments: - -{match_args.play} - -``` -$ ./match_args Rust -This is not the answer. -$ ./match_args 42 -This is the answer! -$ ./match_args do something -error: second argument not an integer -usage: -match_args - Check whether given string is the answer. -match_args {increase|decrease} - Increase or decrease given integer by one. -$ ./match_args do 42 -error: invalid command -usage: -match_args - Check whether given string is the answer. -match_args {increase|decrease} - Increase or decrease given integer by one. -$ ./match_args increase 42 -43 -``` diff --git a/examples/std_misc/arg/matching/match_args.rs b/examples/std_misc/arg/matching/match_args.rs deleted file mode 100644 index bb8e7cc666..0000000000 --- a/examples/std_misc/arg/matching/match_args.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::env; - -fn increase(number: i32) { - println!("{}", number + 1); -} - -fn decrease(number: i32) { - println!("{}", number - 1); -} - -fn help() { - println!("usage: -match_args - Check whether given string is the answer. -match_args {{increase|decrease}} - Increase or decrease given integer by one."); -} - -fn main() { - let args: Vec = env::args().collect(); - - match args.len() { - // no arguments passed - 1 => { - println!("My name is 'match_args'. Try passing some arguments!"); - }, - // one argument passed - 2 => { - match args[1].parse() { - Ok(42) => println!("This is the answer!"), - _ => println!("This is not the answer."), - } - }, - // one command and one argument passed - 3 => { - let cmd = &args[1]; - let num = &args[2]; - // parse the number - let number: i32 = match num.parse() { - Ok(n) => { - n - }, - Err(_) => { - println!("error: second argument not an integer"); - help(); - return; - }, - }; - // parse the command - match &cmd[..] { - "increase" => increase(number), - "decrease" => decrease(number), - _ => { - println!("error: invalid command"); - help(); - }, - } - }, - // all the other cases - _ => { - // show a help message - help(); - } - } -} diff --git a/examples/std_misc/channels/channels.rs b/examples/std_misc/channels/channels.rs deleted file mode 100644 index fb03ec1d2f..0000000000 --- a/examples/std_misc/channels/channels.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::sync::mpsc::{Sender, Receiver}; -use std::sync::mpsc; -use std::thread; - -static NTHREADS: i32 = 3; - -fn main() { - // Channels have two endpoints: the `Sender` and the `Receiver`, - // where `T` is the type of the message to be transferred - // (type annotation is superfluous) - let (tx, rx): (Sender, Receiver) = mpsc::channel(); - - for id in 0..NTHREADS { - // The sender endpoint can be copied - let thread_tx = tx.clone(); - - // Each thread will send its id via the channel - thread::spawn(move || { - // The thread takes ownership over `thread_tx` - // Each thread queues a message in the channel - thread_tx.send(id).unwrap(); - - // Sending is a non-blocking operation, the thread will continue - // immediately after sending its message - println!("thread {} finished", id); - }); - } - - // Here, all the messages are collected - let mut ids = Vec::with_capacity(NTHREADS as usize); - for _ in 0..NTHREADS { - // The `recv` method picks a message from the channel - // `recv` will block the current thread if there are no messages available - ids.push(rx.recv()); - } - - // Show the order in which the messages were sent - println!("{:?}", ids); -} diff --git a/examples/std_misc/channels/input.md b/examples/std_misc/channels/input.md deleted file mode 100644 index a7edabc1a5..0000000000 --- a/examples/std_misc/channels/input.md +++ /dev/null @@ -1,5 +0,0 @@ -Rust provides asynchronous `channels` for communication between threads. Channels -allow a unidirectional flow of information between two end-points: the -`Sender` and the `Receiver`. - -{channels.play} diff --git a/examples/std_misc/ffi/ffi.rs b/examples/std_misc/ffi/ffi.rs deleted file mode 100644 index f96f7a0d54..0000000000 --- a/examples/std_misc/ffi/ffi.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::fmt; - -// this extern block links to the libm library -#[link(name = "m")] -extern { - // this is a foreign function - // that computes the square root of a single precision complex number - fn csqrtf(z: Complex) -> Complex; -} - -fn main() { - // z = -1 + 0i - let z = Complex { re: -1., im: 0. }; - - // calling a foreign function is an unsafe operation - let z_sqrt = unsafe { - csqrtf(z) - }; - - println!("the square root of {:?} is {:?}", z, z_sqrt); -} - -// Minimal implementation of single precision complex numbers -#[repr(C)] -#[derive(Clone, Copy)] -struct Complex { - re: f32, - im: f32, -} - -impl fmt::Debug for Complex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.im < 0. { - write!(f, "{}-{}i", self.re, -self.im) - } else { - write!(f, "{}+{}i", self.re, self.im) - } - } -} diff --git a/examples/std_misc/ffi/input.md b/examples/std_misc/ffi/input.md deleted file mode 100644 index c68369df39..0000000000 --- a/examples/std_misc/ffi/input.md +++ /dev/null @@ -1,14 +0,0 @@ -Rust provides a Foreign Function Interface (FFI) to C libraries. Foreign -functions must be declared inside an `extern` block annotated with a `#[link]` -attribute containing the name of the foreign library. - -{ffi.rs} - -{ffi.out} - -Since calling foreign functions is considered unsafe, it's common to write safe -wrappers around them. - -{safe.rs} - -{safe.out} diff --git a/examples/std_misc/ffi/safe.rs b/examples/std_misc/ffi/safe.rs deleted file mode 100644 index 522f6e04de..0000000000 --- a/examples/std_misc/ffi/safe.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fmt; - -#[link(name = "m")] -extern { - fn ccosf(z: Complex) -> Complex; -} - -// safe wrapper -fn cos(z: Complex) -> Complex { - unsafe { ccosf(z) } -} - -fn main() { - // z = 0 + 1i - let z = Complex { re: 0., im: 1. }; - - println!("cos({:?}) = {:?}", z, cos(z)); -} - -// Minimal implementation of single precision complex numbers -#[repr(C)] -#[derive(Clone, Copy)] -struct Complex { - re: f32, - im: f32, -} - -impl fmt::Debug for Complex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.im < 0. { - write!(f, "{}-{}i", self.re, -self.im) - } else { - write!(f, "{}+{}i", self.re, self.im) - } - } -} diff --git a/examples/std_misc/file/create/create.rs b/examples/std_misc/file/create/create.rs deleted file mode 100644 index 4fd64ff022..0000000000 --- a/examples/std_misc/file/create/create.rs +++ /dev/null @@ -1,35 +0,0 @@ -static LOREM_IPSUM: &'static str = -"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -"; - -use std::error::Error; -use std::io::prelude::*; -use std::fs::File; -use std::path::Path; - -fn main() { - let path = Path::new("out/lorem_ipsum.txt"); - let display = path.display(); - - // Open a file in write-only mode, returns `io::Result` - let mut file = match File::create(&path) { - Err(why) => panic!("couldn't create {}: {}", - display, - why.description()), - Ok(file) => file, - }; - - // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>` - match file.write_all(LOREM_IPSUM.as_bytes()) { - Err(why) => { - panic!("couldn't write to {}: {}", display, - why.description()) - }, - Ok(_) => println!("successfully wrote to {}", display), - } -} diff --git a/examples/std_misc/file/create/input.md b/examples/std_misc/file/create/input.md deleted file mode 100644 index e99a09ab18..0000000000 --- a/examples/std_misc/file/create/input.md +++ /dev/null @@ -1,26 +0,0 @@ -The `create` static method opens a file in write-only mode. If the file -already existed, the old content is destroyed. Otherwise, a new file is -created. - -{create.rs} - -Here's the expected successful output: - -``` -$ mkdir out -$ rustc create.rs && ./create -successfully wrote to out/lorem_ipsum.txt -$ cat out/lorem_ipsum.txt -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -``` - -(As in the previous example, you are encouraged to test this example under -failure conditions.) - -There is also a more generic `open_mode` method that can open files in other -modes like: read+write, append, etc. diff --git a/examples/std_misc/file/input.md b/examples/std_misc/file/input.md deleted file mode 100644 index 2dd1039471..0000000000 --- a/examples/std_misc/file/input.md +++ /dev/null @@ -1,9 +0,0 @@ -The `File` struct represents a file that has been opened (it wraps a file -descriptor), and gives read and/or write access to the underlying file. - -Since many things can go wrong when doing file I/O, all the `File` methods -return the `io::Result` type, which is an alias for `Result`. - -This makes the failure of all I/O operations *explicit*. Thanks to this, the -programmer can see all the failure paths, and is encouraged to handle them in -a proactive manner. diff --git a/examples/std_misc/file/open/input.md b/examples/std_misc/file/open/input.md deleted file mode 100644 index bc5e51df22..0000000000 --- a/examples/std_misc/file/open/input.md +++ /dev/null @@ -1,19 +0,0 @@ -The `open` static method can be used to open a file in read-only mode. - -A `File` owns a resource, the file descriptor and takes care of closing the -file when it is `drop`ed. - -{open.rs} - -Here's the expected successful output: - -``` -$ echo "Hello World!" > hello.txt -$ rustc open.rs && ./open -hello.txt contains: -Hello World! -``` - -(You are encouraged to test the previous example under different failure -conditions: `hello.txt` doesn't exist, or `hello.txt` is not readable, -etc.) diff --git a/examples/std_misc/file/open/open.rs b/examples/std_misc/file/open/open.rs deleted file mode 100644 index d97517cd39..0000000000 --- a/examples/std_misc/file/open/open.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::error::Error; -use std::fs::File; -use std::io::prelude::*; -use std::path::Path; - -fn main() { - // Create a path to the desired file - let path = Path::new("hello.txt"); - let display = path.display(); - - // Open the path in read-only mode, returns `io::Result` - let mut file = match File::open(&path) { - // The `description` method of `io::Error` returns a string that - // describes the error - Err(why) => panic!("couldn't open {}: {}", display, - why.description()), - Ok(file) => file, - }; - - // Read the file contents into a string, returns `io::Result` - let mut s = String::new(); - match file.read_to_string(&mut s) { - Err(why) => panic!("couldn't read {}: {}", display, - why.description()), - Ok(_) => print!("{} contains:\n{}", display, s), - } - - // `file` goes out of scope, and the "hello.txt" file gets closed -} diff --git a/examples/std_misc/fs/fs.rs b/examples/std_misc/fs/fs.rs deleted file mode 100644 index d893bef58b..0000000000 --- a/examples/std_misc/fs/fs.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::fs; -use std::fs::{File, OpenOptions}; -use std::io; -use std::io::prelude::*; -use std::os::unix; -use std::path::Path; - -// A simple implementation of `% cat path` -fn cat(path: &Path) -> io::Result { - let mut f = try!(File::open(path)); - let mut s = String::new(); - match f.read_to_string(&mut s) { - Ok(_) => Ok(s), - Err(e) => Err(e), - } -} - -// A simple implementation of `% echo s > path` -fn echo(s: &str, path: &Path) -> io::Result<()> { - let mut f = try!(File::create(path)); - - f.write_all(s.as_bytes()) -} - -// A simple implementation of `% touch path` (ignores existing files) -fn touch(path: &Path) -> io::Result<()> { - match OpenOptions::new().create(true).write(true).open(path) { - Ok(_) => Ok(()), - Err(e) => Err(e), - } -} - -fn main() { - println!("`mkdir a`"); - // Create a directory, returns `io::Result<()>` - match fs::create_dir("a") { - Err(why) => println!("! {:?}", why.kind()), - Ok(_) => {}, - } - - println!("`echo hello > a/b.txt`"); - // The previous match can be simplified using the `unwrap_or_else` method - echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); - - println!("`mkdir -p a/c/d`"); - // Recursively create a directory, returns `io::Result<()>` - fs::create_dir_all("a/c/d").unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); - - println!("`touch a/c/e.txt`"); - touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); - - println!("`ln -s ../b.txt a/c/b.txt`"); - // Create a symbolic link, returns `io::Result<()>` - if cfg!(target_family = "unix") { - unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); - } - - println!("`cat a/c/b.txt`"); - match cat(&Path::new("a/c/b.txt")) { - Err(why) => println!("! {:?}", why.kind()), - Ok(s) => println!("> {}", s), - } - - println!("`ls a`"); - // Read the contents of a directory, returns `io::Result>` - match fs::read_dir("a") { - Err(why) => println!("! {:?}", why.kind()), - Ok(paths) => for path in paths { - println!("> {:?}", path.unwrap().path()); - }, - } - - println!("`rm a/c/e.txt`"); - // Remove a file, returns `io::Result<()>` - fs::remove_file("a/c/e.txt").unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); - - println!("`rmdir a/c/d`"); - // Remove an empty directory, returns `io::Result<()>` - fs::remove_dir("a/c/d").unwrap_or_else(|why| { - println!("! {:?}", why.kind()); - }); -} diff --git a/examples/std_misc/fs/input.md b/examples/std_misc/fs/input.md deleted file mode 100644 index 1241e16d09..0000000000 --- a/examples/std_misc/fs/input.md +++ /dev/null @@ -1,40 +0,0 @@ -The `std::io::fs` module contains several functions that deal with the -filesystem. - -{fs.rs} - -Here's the expected successful output: - -``` -$ rustc fs.rs && ./fs -`mkdir a` -`echo hello > a/b.txt` -`mkdir -p a/c/d` -`touch a/c/e.txt` -`ln -s ../b.txt a/c/b.txt` -`cat a/c/b.txt` -> hello -`ls a` -> "a/b.txt" -> "a/c" -`rm a/c/e.txt` -`rmdir a/c/d` -``` - -And the final state of the `a` directory is: - -``` -$ tree a -a -|-- b.txt -`-- c - `-- b.txt -> ../b.txt - -1 directory, 2 files -``` - -### See also: - -[`cfg!`][cfg] - -[cfg]: /attribute/cfg.html diff --git a/examples/std_misc/input.md b/examples/std_misc/input.md deleted file mode 100644 index ad3ba643eb..0000000000 --- a/examples/std_misc/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Many other types are provided by the std library to support -things such as: - -* Threads -* Channels -* File I/O - -These expand beyond what the [primitives][primitives] provide. - -### See also: - -[primitives][primitives] and [the std library][std] - -[primitives]: /primitives.html -[std]: https://doc.rust-lang.org/std/ diff --git a/examples/std_misc/path/input.md b/examples/std_misc/path/input.md deleted file mode 100644 index 45cdfbc49e..0000000000 --- a/examples/std_misc/path/input.md +++ /dev/null @@ -1,24 +0,0 @@ -The `Path` struct represents file paths in the underlying filesystem. There are -two flavors of `Path`: `posix::Path`, for UNIX-like systems, and -`windows::Path`, for Windows. The prelude exports the appropriate -platform-specific `Path` variant. - -A `Path` can be created from almost any type that implements the -`OsStr` trait, like a string, and provides several methods to get -information from the file/directory the path points to. - -Note that a `Path` is *not* internally represented as an UTF-8 string, but -instead is stored as a vector of bytes (`Vec`). Therefore, converting a -`Path` to a `&str` is *not* free and may fail (an `Option` is returned). - -{path.play} - -Be sure to check at other `Path` methods (`posix::Path` or `windows::Path`) and -the `Metadata` struct. - -### See also - -[OsStr][1] and [Metadata][2]. - -[1]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html -[2]: https://doc.rust-lang.org/std/fs/struct.Metadata.html diff --git a/examples/std_misc/path/path.rs b/examples/std_misc/path/path.rs deleted file mode 100644 index 96824b6f40..0000000000 --- a/examples/std_misc/path/path.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::path::Path; - -fn main() { - // Create a `Path` from an `&'static str` - let path = Path::new("."); - - // The `display` method returns a `Show`able structure - let _display = path.display(); - - // `join` merges a path with a byte container using the OS specific - // separator, and returns the new path - let new_path = path.join("a").join("b"); - - // Convert the path into a string slice - match new_path.to_str() { - None => panic!("new path is not a valid UTF-8 sequence"), - Some(s) => println!("new path is {}", s), - } -} diff --git a/examples/std_misc/process/input.md b/examples/std_misc/process/input.md deleted file mode 100644 index 06c2ce6ec2..0000000000 --- a/examples/std_misc/process/input.md +++ /dev/null @@ -1,7 +0,0 @@ -The `process::Output` struct represents the output of a finished child process, -and the `process::Command` struct is a process builder. - -{process.play} - -(You are encouraged to try the previous example with an incorrect flag passed -to `rustc`) diff --git a/examples/std_misc/process/pipe/input.md b/examples/std_misc/process/pipe/input.md deleted file mode 100644 index 4d3e2744bf..0000000000 --- a/examples/std_misc/process/pipe/input.md +++ /dev/null @@ -1,5 +0,0 @@ -The `std::Child` struct represents a running child process, and exposes the -`stdin`, `stdout` and `stderr` handles for interaction with the underlying -process via pipes. - -{pipe.play} diff --git a/examples/std_misc/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs deleted file mode 100644 index fa33e845a5..0000000000 --- a/examples/std_misc/process/pipe/pipe.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::error::Error; -use std::io::prelude::*; -use std::process::{Command, Stdio}; - -static PANGRAM: &'static str = -"the quick brown fox jumped over the lazy dog\n"; - -fn main() { - // Spawn the `wc` command - let process = match Command::new("wc") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() { - Err(why) => panic!("couldn't spawn wc: {}", why.description()), - Ok(process) => process, - }; - - // Write a string to the `stdin` of `wc`. - // - // `stdin` has type `Option`, but since we know this instance - // must have one, we can directly `unwrap` it. - match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { - Err(why) => panic!("couldn't write to wc stdin: {}", - why.description()), - Ok(_) => println!("sent pangram to wc"), - } - - // Because `stdin` does not live after the above calls, it is `drop`ed, - // and the pipe is closed. - // - // This is very important, otherwise `wc` wouldn't start processing the - // input we just sent. - - // The `stdout` field also has type `Option` so must be unwrapped. - let mut s = String::new(); - match process.stdout.unwrap().read_to_string(&mut s) { - Err(why) => panic!("couldn't read wc stdout: {}", - why.description()), - Ok(_) => print!("wc responded with:\n{}", s), - } -} diff --git a/examples/std_misc/process/process.rs b/examples/std_misc/process/process.rs deleted file mode 100644 index 62562612f8..0000000000 --- a/examples/std_misc/process/process.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::process::Command; - -fn main() { - let output = Command::new("rustc") - .arg("--version") - .output().unwrap_or_else(|e| { - panic!("failed to execute process: {}", e) - }); - - if output.status.success() { - let s = String::from_utf8_lossy(&output.stdout); - - print!("rustc succeeded and stdout was:\n{}", s); - } else { - let s = String::from_utf8_lossy(&output.stderr); - - print!("rustc failed and stderr was:\n{}", s); - } -} diff --git a/examples/std_misc/process/wait/input.md b/examples/std_misc/process/wait/input.md deleted file mode 100644 index 33076ab95b..0000000000 --- a/examples/std_misc/process/wait/input.md +++ /dev/null @@ -1,11 +0,0 @@ -If you'd like to wait for a `process::Child` to finish, you must call -`Child::wait`, which will return a `process::ExitStatus`. - -{wait.rs} - -``` -$ rustc wait.rs && ./wait -reached end of main -# `wait` keeps running for 5 seconds -# `sleep 5` command ends, and then our `wait` program finishes -``` diff --git a/examples/std_misc/process/wait/wait.rs b/examples/std_misc/process/wait/wait.rs deleted file mode 100644 index c5010652df..0000000000 --- a/examples/std_misc/process/wait/wait.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::process::Command; - -fn main() { - let mut child = Command::new("sleep").arg("5").spawn().unwrap(); - let _result = child.wait().unwrap(); - - println!("reached end of main"); -} diff --git a/examples/std_misc/threads/input.md b/examples/std_misc/threads/input.md deleted file mode 100644 index 6b304c720a..0000000000 --- a/examples/std_misc/threads/input.md +++ /dev/null @@ -1,6 +0,0 @@ -Rust provides a mechanism for spawning native OS threads via the `spawn` -function, the argument of this function is a moving closure. - -{threads.play} - -These threads will be scheduled by the OS. diff --git a/examples/std_misc/threads/testcase_mapreduce/input.md b/examples/std_misc/threads/testcase_mapreduce/input.md deleted file mode 100644 index 936fd9f784..0000000000 --- a/examples/std_misc/threads/testcase_mapreduce/input.md +++ /dev/null @@ -1,48 +0,0 @@ -Rust makes it very easy to parallelise data processing, without many of the headaches traditionally associated with such an attempt. - -The standard library provides great threading primitives out of the box. -These, combined with Rust's concept of Ownership and aliasing rules, automatically prevent -data races. - -The aliasing rules (one writable reference XOR many readable references) automatically prevent -you from manipulating state that is visible to other threads. (Where synchronisation is needed, -there are synchronisation -primitives like `Mutex`es or `Channel`s.) - -In this example, we will calculate the sum of all digits in a block of numbers. -We will do this by parcelling out chunks of the block into different threads. Each thread will sum -its tiny block of digits, and subsequently we will sum the intermediate sums produced by each -thread. - -Note that, although we're passing references across thread boundaries, Rust understands that we're -only passing read-only references, and that thus no unsafety or data races can occur. Because -we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive -until the threads exit, so no dangling pointers occur. - -{mapreduce.play} - -### Assignments -It is not wise to let our number of threads depend on user inputted data. -What if the user decides to insert a lot of spaces? Do we _really_ want to spawn 2,000 threads? -Modify the program so that the data is always chunked into a limited number of chunks, -defined by a static constant at the beginning of the program. - -### See also: -* [Threads][thread] -* [vectors][vectors] and [iterators][iterators] -* [closures][closures], [move][move] semantics and [`move` closures][move_closure] -* [destructuring][destructuring] assignments -* [turbofish notation][turbofish] to help type inference -* [unwrap vs. expect][unwrap] -* [enumerate][enumerate] - -[thread]: /std_misc/threads.html -[vectors]: /std/vec.html -[iterators]: /trait/iter.html -[destructuring]: https://doc.rust-lang.org/book/patterns.html#destructuring -[closures]: /fn/closures.html -[move]: /scope/move.html -[move_closure]: https://doc.rust-lang.org/book/closures.html#move-closures -[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect -[unwrap]: /error/option_unwrap.html -[enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate diff --git a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs b/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs deleted file mode 100644 index 6ad15f83d8..0000000000 --- a/examples/std_misc/threads/testcase_mapreduce/mapreduce.rs +++ /dev/null @@ -1,100 +0,0 @@ -use std::thread; - -// This is the `main` thread -fn main() { - - // This is our data to process. - // We will calculate the sum of all digits via a threaded map-reduce algorithm. - // Each whitespace separated chunk will be handled in a different thread. - // - // TODO: see what happens to the output if you insert spaces! - let data = "86967897737416471853297327050364959 -11861322575564723963297542624962850 -70856234701860851907960690014725639 -38397966707106094172783238747669219 -52380795257888236525459303330302837 -58495327135744041048897885734297812 -69920216438980873548808413720956532 -16278424637452589860345374828574668"; - - // Make a vector to hold the child-threads which we will spawn. - let mut children = vec![]; - - /************************************************************************* - * "Map" phase - * - * Divide our data into segments, and apply initial processing - ************************************************************************/ - - // split our data into segments for individual calculation - // each chunk will be a reference (&str) into the actual data - let chunked_data = data.split_whitespace(); - - // Iterate over the data segments. - // .enumerate() adds the current loop index to whatever is iterated - // the resulting tuple "(index, element)" is then immediately - // "destructured" into two variables, "i" and "data_segment" with a - // "destructuring assignment" - for (i, data_segment) in chunked_data.enumerate() { - println!("data segment {} is \"{}\"", i, data_segment); - - // Process each data segment in a separate thread - // - // spawn() returns a handle to the new thread, - // which we MUST keep to access the returned value - // - // 'move || -> u32' is syntax for a closure that: - // * takes no arguments ('||') - // * takes ownership of its captured variables ('move') and - // * returns an unsigned 32-bit integer ('-> u32') - // - // Rust is smart enough to infer the '-> u32' from - // the closure itself so we could have left that out. - // - // TODO: try removing the 'move' and see what happens - children.push(thread::spawn(move || -> u32 { - // Calculate the intermediate sum of this segment: - let result = data_segment - // iterate over the characters of our segment.. - .chars() - // .. convert text-characters to their number value.. - .map(|c| c.to_digit(10).expect("should be a digit")) - // .. and sum the resulting iterator of numbers - .sum(); - - // println! locks stdout, so no text-interleaving occurs - println!("processed segment {}, result={}", i, result); - - // "return" not needed, because Rust is an "expression language", the - // last evaluated expression in each block is automatically its value. - result - - })); - } - - - /************************************************************************* - * "Reduce" phase - * - * Collect our intermediate results, and combine them into a final result - ************************************************************************/ - - // collect each thread's intermediate results into a new Vec - let mut intermediate_sums = vec![]; - for child in children { - // collect each child thread's return-value - let intermediate_sum = child.join().unwrap(); - intermediate_sums.push(intermediate_sum); - } - - // combine all intermediate sums into a single final sum. - // - // we use the "turbofish" ::<> to provide sum() with a type hint. - // - // TODO: try without the turbofish, by instead explicitly - // specifying the type of intermediate_sums - let final_result = intermediate_sums.iter().sum::(); - - println!("Final sum result: {}", final_result); -} - diff --git a/examples/std_misc/threads/threads.rs b/examples/std_misc/threads/threads.rs deleted file mode 100644 index a0b8c37995..0000000000 --- a/examples/std_misc/threads/threads.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::thread; - -static NTHREADS: i32 = 10; - -// This is the `main` thread -fn main() { - // Make a vector to hold the children which are spawned. - let mut children = vec![]; - - for i in 0..NTHREADS { - // Spin up another thread - children.push(thread::spawn(move || { - println!("this is thread number {}", i) - })); - } - - for child in children { - // Wait for the thread to finish. Returns a result. - let _ = child.join(); - } -} diff --git a/src/std_misc.md b/src/std_misc.md index 786e6e6a31..c170428bfe 100644 --- a/src/std_misc.md +++ b/src/std_misc.md @@ -1 +1,17 @@ # Std misc + +Many other types are provided by the std library to support +things such as: + +* Threads +* Channels +* File I/O + +These expand beyond what the [primitives][primitives] provide. + +### See also: + +[primitives][primitives] and [the std library][std] + +[primitives]: /primitives.html +[std]: https://doc.rust-lang.org/std/ diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md index 7c83fad5c3..5af20a0d48 100644 --- a/src/std_misc/arg.md +++ b/src/std_misc/arg.md @@ -1 +1,26 @@ # Program arguments + +The command line arguments can be accessed using `std::env::args`, which +returns an iterator that yields a String for each argument: + +```rust,editable +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + + // The first argument is the path that was used to call the program. + println!("My path is {}.", args[0]); + + // The rest of the arguments are the passed command line parameters. + // Call the program like this: + // $ ./args arg1 arg2 + println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]); +} +``` + +```bash +$ ./args 1 2 3 +My path is ./args. +I got 3 arguments: ["1", "2", "3"]. +``` diff --git a/src/std_misc/arg/matching.md b/src/std_misc/arg/matching.md index 2b897c0013..03942683f3 100644 --- a/src/std_misc/arg/matching.md +++ b/src/std_misc/arg/matching.md @@ -1 +1,94 @@ # Argument parsing + +Matching can be used to parse simple arguments: + +```rust,editable +use std::env; + +fn increase(number: i32) { + println!("{}", number + 1); +} + +fn decrease(number: i32) { + println!("{}", number - 1); +} + +fn help() { + println!("usage: +match_args + Check whether given string is the answer. +match_args {{increase|decrease}} + Increase or decrease given integer by one."); +} + +fn main() { + let args: Vec = env::args().collect(); + + match args.len() { + // no arguments passed + 1 => { + println!("My name is 'match_args'. Try passing some arguments!"); + }, + // one argument passed + 2 => { + match args[1].parse() { + Ok(42) => println!("This is the answer!"), + _ => println!("This is not the answer."), + } + }, + // one command and one argument passed + 3 => { + let cmd = &args[1]; + let num = &args[2]; + // parse the number + let number: i32 = match num.parse() { + Ok(n) => { + n + }, + Err(_) => { + println!("error: second argument not an integer"); + help(); + return; + }, + }; + // parse the command + match &cmd[..] { + "increase" => increase(number), + "decrease" => decrease(number), + _ => { + println!("error: invalid command"); + help(); + }, + } + }, + // all the other cases + _ => { + // show a help message + help(); + } + } +} +``` + +```bash +$ ./match_args Rust +This is not the answer. +$ ./match_args 42 +This is the answer! +$ ./match_args do something +error: second argument not an integer +usage: +match_args + Check whether given string is the answer. +match_args {increase|decrease} + Increase or decrease given integer by one. +$ ./match_args do 42 +error: invalid command +usage: +match_args + Check whether given string is the answer. +match_args {increase|decrease} + Increase or decrease given integer by one. +$ ./match_args increase 42 +43 +``` \ No newline at end of file diff --git a/src/std_misc/channels.md b/src/std_misc/channels.md index a3c35c63e0..e88605543f 100644 --- a/src/std_misc/channels.md +++ b/src/std_misc/channels.md @@ -1 +1,47 @@ # Channels + +Rust provides asynchronous `channels` for communication between threads. Channels +allow a unidirectional flow of information between two end-points: the +`Sender` and the `Receiver`. + +```rust,editable +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; +use std::thread; + +static NTHREADS: i32 = 3; + +fn main() { + // Channels have two endpoints: the `Sender` and the `Receiver`, + // where `T` is the type of the message to be transferred + // (type annotation is superfluous) + let (tx, rx): (Sender, Receiver) = mpsc::channel(); + + for id in 0..NTHREADS { + // The sender endpoint can be copied + let thread_tx = tx.clone(); + + // Each thread will send its id via the channel + thread::spawn(move || { + // The thread takes ownership over `thread_tx` + // Each thread queues a message in the channel + thread_tx.send(id).unwrap(); + + // Sending is a non-blocking operation, the thread will continue + // immediately after sending its message + println!("thread {} finished", id); + }); + } + + // Here, all the messages are collected + let mut ids = Vec::with_capacity(NTHREADS as usize); + for _ in 0..NTHREADS { + // The `recv` method picks a message from the channel + // `recv` will block the current thread if there are no messages available + ids.push(rx.recv()); + } + + // Show the order in which the messages were sent + println!("{:?}", ids); +} +``` \ No newline at end of file diff --git a/src/std_misc/ffi.md b/src/std_misc/ffi.md index 32a37da5f4..baddf05ab7 100644 --- a/src/std_misc/ffi.md +++ b/src/std_misc/ffi.md @@ -1 +1,89 @@ # Foreign Function Interface + +Rust provides a Foreign Function Interface (FFI) to C libraries. Foreign +functions must be declared inside an `extern` block annotated with a `#[link]` +attribute containing the name of the foreign library. + +```rust,editable +use std::fmt; + +// this extern block links to the libm library +#[link(name = "m")] +extern { + // this is a foreign function + // that computes the square root of a single precision complex number + fn csqrtf(z: Complex) -> Complex; +} + +fn main() { + // z = -1 + 0i + let z = Complex { re: -1., im: 0. }; + + // calling a foreign function is an unsafe operation + let z_sqrt = unsafe { + csqrtf(z) + }; + + println!("the square root of {:?} is {:?}", z, z_sqrt); +} + +// Minimal implementation of single precision complex numbers +#[repr(C)] +#[derive(Clone, Copy)] +struct Complex { + re: f32, + im: f32, +} + +impl fmt::Debug for Complex { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.im < 0. { + write!(f, "{}-{}i", self.re, -self.im) + } else { + write!(f, "{}+{}i", self.re, self.im) + } + } +} +``` + +Since calling foreign functions is considered unsafe, it's common to write safe +wrappers around them. + +```rust,editable +use std::fmt; + +#[link(name = "m")] +extern { + fn ccosf(z: Complex) -> Complex; +} + +// safe wrapper +fn cos(z: Complex) -> Complex { + unsafe { ccosf(z) } +} + +fn main() { + // z = 0 + 1i + let z = Complex { re: 0., im: 1. }; + + println!("cos({:?}) = {:?}", z, cos(z)); +} + +// Minimal implementation of single precision complex numbers +#[repr(C)] +#[derive(Clone, Copy)] +struct Complex { + re: f32, + im: f32, +} + +impl fmt::Debug for Complex { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.im < 0. { + write!(f, "{}-{}i", self.re, -self.im) + } else { + write!(f, "{}+{}i", self.re, self.im) + } + } +} +``` \ No newline at end of file diff --git a/src/std_misc/file.md b/src/std_misc/file.md index 6c83a9a5cf..60e28cfb3d 100644 --- a/src/std_misc/file.md +++ b/src/std_misc/file.md @@ -1 +1,11 @@ # File I/O + +The `File` struct represents a file that has been opened (it wraps a file +descriptor), and gives read and/or write access to the underlying file. + +Since many things can go wrong when doing file I/O, all the `File` methods +return the `io::Result` type, which is an alias for `Result`. + +This makes the failure of all I/O operations *explicit*. Thanks to this, the +programmer can see all the failure paths, and is encouraged to handle them in +a proactive manner. \ No newline at end of file diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md index 93a3968731..495c1c40a3 100644 --- a/src/std_misc/file/create.md +++ b/src/std_misc/file/create.md @@ -1 +1,64 @@ # `create` + +The `create` static method opens a file in write-only mode. If the file +already existed, the old content is destroyed. Otherwise, a new file is +created. + +```rust,editable +static LOREM_IPSUM: &'static str = +"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non +proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +"; + +use std::error::Error; +use std::io::prelude::*; +use std::fs::File; +use std::path::Path; + +fn main() { + let path = Path::new("out/lorem_ipsum.txt"); + let display = path.display(); + + // Open a file in write-only mode, returns `io::Result` + let mut file = match File::create(&path) { + Err(why) => panic!("couldn't create {}: {}", + display, + why.description()), + Ok(file) => file, + }; + + // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>` + match file.write_all(LOREM_IPSUM.as_bytes()) { + Err(why) => { + panic!("couldn't write to {}: {}", display, + why.description()) + }, + Ok(_) => println!("successfully wrote to {}", display), + } +} +``` + +Here's the expected successful output: + +```bash +$ mkdir out +$ rustc create.rs && ./create +successfully wrote to out/lorem_ipsum.txt +$ cat out/lorem_ipsum.txt +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non +proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +``` + +(As in the previous example, you are encouraged to test this example under +failure conditions.) + +There is also a more generic `open_mode` method that can open files in other +modes like: read+write, append, etc. diff --git a/src/std_misc/file/open.md b/src/std_misc/file/open.md index 485a3dad64..8871c2b591 100644 --- a/src/std_misc/file/open.md +++ b/src/std_misc/file/open.md @@ -1 +1,52 @@ # `open` + +The `open` static method can be used to open a file in read-only mode. + +A `File` owns a resource, the file descriptor and takes care of closing the +file when it is `drop`ed. + +```rust,editable +use std::error::Error; +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; + +fn main() { + // Create a path to the desired file + let path = Path::new("hello.txt"); + let display = path.display(); + + // Open the path in read-only mode, returns `io::Result` + let mut file = match File::open(&path) { + // The `description` method of `io::Error` returns a string that + // describes the error + Err(why) => panic!("couldn't open {}: {}", display, + why.description()), + Ok(file) => file, + }; + + // Read the file contents into a string, returns `io::Result` + let mut s = String::new(); + match file.read_to_string(&mut s) { + Err(why) => panic!("couldn't read {}: {}", display, + why.description()), + Ok(_) => print!("{} contains:\n{}", display, s), + } + + // `file` goes out of scope, and the "hello.txt" file gets closed +} + +``` + +Here's the expected successful output: + +```bash +$ echo "Hello World!" > hello.txt +$ rustc open.rs && ./open +hello.txt contains: +Hello World! +``` + +(You are encouraged to test the previous example under different failure +conditions: `hello.txt` doesn't exist, or `hello.txt` is not readable, +etc.) diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index 57dcafcc83..6299f5e804 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -1 +1,136 @@ # Filesystem Operations + +The `std::io::fs` module contains several functions that deal with the +filesystem. + +```rust,editable +use std::fs; +use std::fs::{File, OpenOptions}; +use std::io; +use std::io::prelude::*; +use std::os::unix; +use std::path::Path; + +// A simple implementation of `% cat path` +fn cat(path: &Path) -> io::Result { + let mut f = try!(File::open(path)); + let mut s = String::new(); + match f.read_to_string(&mut s) { + Ok(_) => Ok(s), + Err(e) => Err(e), + } +} + +// A simple implementation of `% echo s > path` +fn echo(s: &str, path: &Path) -> io::Result<()> { + let mut f = try!(File::create(path)); + + f.write_all(s.as_bytes()) +} + +// A simple implementation of `% touch path` (ignores existing files) +fn touch(path: &Path) -> io::Result<()> { + match OpenOptions::new().create(true).write(true).open(path) { + Ok(_) => Ok(()), + Err(e) => Err(e), + } +} + +fn main() { + println!("`mkdir a`"); + // Create a directory, returns `io::Result<()>` + match fs::create_dir("a") { + Err(why) => println!("! {:?}", why.kind()), + Ok(_) => {}, + } + + println!("`echo hello > a/b.txt`"); + // The previous match can be simplified using the `unwrap_or_else` method + echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); + + println!("`mkdir -p a/c/d`"); + // Recursively create a directory, returns `io::Result<()>` + fs::create_dir_all("a/c/d").unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); + + println!("`touch a/c/e.txt`"); + touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); + + println!("`ln -s ../b.txt a/c/b.txt`"); + // Create a symbolic link, returns `io::Result<()>` + if cfg!(target_family = "unix") { + unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); + } + + println!("`cat a/c/b.txt`"); + match cat(&Path::new("a/c/b.txt")) { + Err(why) => println!("! {:?}", why.kind()), + Ok(s) => println!("> {}", s), + } + + println!("`ls a`"); + // Read the contents of a directory, returns `io::Result>` + match fs::read_dir("a") { + Err(why) => println!("! {:?}", why.kind()), + Ok(paths) => for path in paths { + println!("> {:?}", path.unwrap().path()); + }, + } + + println!("`rm a/c/e.txt`"); + // Remove a file, returns `io::Result<()>` + fs::remove_file("a/c/e.txt").unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); + + println!("`rmdir a/c/d`"); + // Remove an empty directory, returns `io::Result<()>` + fs::remove_dir("a/c/d").unwrap_or_else(|why| { + println!("! {:?}", why.kind()); + }); +} + +``` + +Here's the expected successful output: + +```bash +$ rustc fs.rs && ./fs +`mkdir a` +`echo hello > a/b.txt` +`mkdir -p a/c/d` +`touch a/c/e.txt` +`ln -s ../b.txt a/c/b.txt` +`cat a/c/b.txt` +> hello +`ls a` +> "a/b.txt" +> "a/c" +`rm a/c/e.txt` +`rmdir a/c/d` +``` + +And the final state of the `a` directory is: + +``` +$ tree a +a +|-- b.txt +`-- c + `-- b.txt -> ../b.txt + +1 directory, 2 files +``` + +### See also: + +[`cfg!`][cfg] + +[cfg]: /attribute/cfg.html diff --git a/src/std_misc/path.md b/src/std_misc/path.md index f541fdb442..e753e29c7f 100644 --- a/src/std_misc/path.md +++ b/src/std_misc/path.md @@ -1 +1,47 @@ # Path + +The `Path` struct represents file paths in the underlying filesystem. There are +two flavors of `Path`: `posix::Path`, for UNIX-like systems, and +`windows::Path`, for Windows. The prelude exports the appropriate +platform-specific `Path` variant. + +A `Path` can be created from almost any type that implements the +`OsStr` trait, like a string, and provides several methods to get +information from the file/directory the path points to. + +Note that a `Path` is *not* internally represented as an UTF-8 string, but +instead is stored as a vector of bytes (`Vec`). Therefore, converting a +`Path` to a `&str` is *not* free and may fail (an `Option` is returned). + +```rust,editable +use std::path::Path; + +fn main() { + // Create a `Path` from an `&'static str` + let path = Path::new("."); + + // The `display` method returns a `Show`able structure + let _display = path.display(); + + // `join` merges a path with a byte container using the OS specific + // separator, and returns the new path + let new_path = path.join("a").join("b"); + + // Convert the path into a string slice + match new_path.to_str() { + None => panic!("new path is not a valid UTF-8 sequence"), + Some(s) => println!("new path is {}", s), + } +} + +``` + +Be sure to check at other `Path` methods (`posix::Path` or `windows::Path`) and +the `Metadata` struct. + +### See also + +[OsStr][1] and [Metadata][2]. + +[1]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html +[2]: https://doc.rust-lang.org/std/fs/struct.Metadata.html diff --git a/src/std_misc/process.md b/src/std_misc/process.md index 71fd4ec252..0f9279f86d 100644 --- a/src/std_misc/process.md +++ b/src/std_misc/process.md @@ -1 +1,29 @@ # Child processes + +The `process::Output` struct represents the output of a finished child process, +and the `process::Command` struct is a process builder. + +```rust,editable +use std::process::Command; + +fn main() { + let output = Command::new("rustc") + .arg("--version") + .output().unwrap_or_else(|e| { + panic!("failed to execute process: {}", e) + }); + + if output.status.success() { + let s = String::from_utf8_lossy(&output.stdout); + + print!("rustc succeeded and stdout was:\n{}", s); + } else { + let s = String::from_utf8_lossy(&output.stderr); + + print!("rustc failed and stderr was:\n{}", s); + } +} +``` + +(You are encouraged to try the previous example with an incorrect flag passed +to `rustc`) diff --git a/src/std_misc/process/pipe.md b/src/std_misc/process/pipe.md index 762f736df6..711ac60b40 100644 --- a/src/std_misc/process/pipe.md +++ b/src/std_misc/process/pipe.md @@ -1 +1,49 @@ # Pipes + +The `std::Child` struct represents a running child process, and exposes the +`stdin`, `stdout` and `stderr` handles for interaction with the underlying +process via pipes. + +```rust,editable +use std::error::Error; +use std::io::prelude::*; +use std::process::{Command, Stdio}; + +static PANGRAM: &'static str = +"the quick brown fox jumped over the lazy dog\n"; + +fn main() { + // Spawn the `wc` command + let process = match Command::new("wc") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() { + Err(why) => panic!("couldn't spawn wc: {}", why.description()), + Ok(process) => process, + }; + + // Write a string to the `stdin` of `wc`. + // + // `stdin` has type `Option`, but since we know this instance + // must have one, we can directly `unwrap` it. + match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { + Err(why) => panic!("couldn't write to wc stdin: {}", + why.description()), + Ok(_) => println!("sent pangram to wc"), + } + + // Because `stdin` does not live after the above calls, it is `drop`ed, + // and the pipe is closed. + // + // This is very important, otherwise `wc` wouldn't start processing the + // input we just sent. + + // The `stdout` field also has type `Option` so must be unwrapped. + let mut s = String::new(); + match process.stdout.unwrap().read_to_string(&mut s) { + Err(why) => panic!("couldn't read wc stdout: {}", + why.description()), + Ok(_) => print!("wc responded with:\n{}", s), + } +} +``` \ No newline at end of file diff --git a/src/std_misc/process/wait.md b/src/std_misc/process/wait.md index 85c3660172..a80378e2fc 100644 --- a/src/std_misc/process/wait.md +++ b/src/std_misc/process/wait.md @@ -1 +1,22 @@ # Wait + +If you'd like to wait for a `process::Child` to finish, you must call +`Child::wait`, which will return a `process::ExitStatus`. + +```rust,editable +use std::process::Command; + +fn main() { + let mut child = Command::new("sleep").arg("5").spawn().unwrap(); + let _result = child.wait().unwrap(); + + println!("reached end of main"); +} +``` + +```bash +$ rustc wait.rs && ./wait +reached end of main +# `wait` keeps running for 5 seconds +# `sleep 5` command ends, and then our `wait` program finishes +``` diff --git a/src/std_misc/threads.md b/src/std_misc/threads.md index f60f3991e1..c3dd0023ac 100644 --- a/src/std_misc/threads.md +++ b/src/std_misc/threads.md @@ -1 +1,30 @@ # Threads + +Rust provides a mechanism for spawning native OS threads via the `spawn` +function, the argument of this function is a moving closure. + +```rust,editable +use std::thread; + +static NTHREADS: i32 = 10; + +// This is the `main` thread +fn main() { + // Make a vector to hold the children which are spawned. + let mut children = vec![]; + + for i in 0..NTHREADS { + // Spin up another thread + children.push(thread::spawn(move || { + println!("this is thread number {}", i) + })); + } + + for child in children { + // Wait for the thread to finish. Returns a result. + let _ = child.join(); + } +} +``` + +These threads will be scheduled by the OS. diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 1b8d5aee08..f3d2b6edd5 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -1 +1,152 @@ # Testcase: map-reduce + +Rust makes it very easy to parallelise data processing, without many of the headaches traditionally associated with such an attempt. + +The standard library provides great threading primitives out of the box. +These, combined with Rust's concept of Ownership and aliasing rules, automatically prevent +data races. + +The aliasing rules (one writable reference XOR many readable references) automatically prevent +you from manipulating state that is visible to other threads. (Where synchronisation is needed, +there are synchronisation +primitives like `Mutex`es or `Channel`s.) + +In this example, we will calculate the sum of all digits in a block of numbers. +We will do this by parcelling out chunks of the block into different threads. Each thread will sum +its tiny block of digits, and subsequently we will sum the intermediate sums produced by each +thread. + +Note that, although we're passing references across thread boundaries, Rust understands that we're +only passing read-only references, and that thus no unsafety or data races can occur. Because +we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive +until the threads exit, so no dangling pointers occur. + +```rust,editable +use std::thread; + +// This is the `main` thread +fn main() { + + // This is our data to process. + // We will calculate the sum of all digits via a threaded map-reduce algorithm. + // Each whitespace separated chunk will be handled in a different thread. + // + // TODO: see what happens to the output if you insert spaces! + let data = "86967897737416471853297327050364959 +11861322575564723963297542624962850 +70856234701860851907960690014725639 +38397966707106094172783238747669219 +52380795257888236525459303330302837 +58495327135744041048897885734297812 +69920216438980873548808413720956532 +16278424637452589860345374828574668"; + + // Make a vector to hold the child-threads which we will spawn. + let mut children = vec![]; + + /************************************************************************* + * "Map" phase + * + * Divide our data into segments, and apply initial processing + ************************************************************************/ + + // split our data into segments for individual calculation + // each chunk will be a reference (&str) into the actual data + let chunked_data = data.split_whitespace(); + + // Iterate over the data segments. + // .enumerate() adds the current loop index to whatever is iterated + // the resulting tuple "(index, element)" is then immediately + // "destructured" into two variables, "i" and "data_segment" with a + // "destructuring assignment" + for (i, data_segment) in chunked_data.enumerate() { + println!("data segment {} is \"{}\"", i, data_segment); + + // Process each data segment in a separate thread + // + // spawn() returns a handle to the new thread, + // which we MUST keep to access the returned value + // + // 'move || -> u32' is syntax for a closure that: + // * takes no arguments ('||') + // * takes ownership of its captured variables ('move') and + // * returns an unsigned 32-bit integer ('-> u32') + // + // Rust is smart enough to infer the '-> u32' from + // the closure itself so we could have left that out. + // + // TODO: try removing the 'move' and see what happens + children.push(thread::spawn(move || -> u32 { + // Calculate the intermediate sum of this segment: + let result = data_segment + // iterate over the characters of our segment.. + .chars() + // .. convert text-characters to their number value.. + .map(|c| c.to_digit(10).expect("should be a digit")) + // .. and sum the resulting iterator of numbers + .sum(); + + // println! locks stdout, so no text-interleaving occurs + println!("processed segment {}, result={}", i, result); + + // "return" not needed, because Rust is an "expression language", the + // last evaluated expression in each block is automatically its value. + result + + })); + } + + + /************************************************************************* + * "Reduce" phase + * + * Collect our intermediate results, and combine them into a final result + ************************************************************************/ + + // collect each thread's intermediate results into a new Vec + let mut intermediate_sums = vec![]; + for child in children { + // collect each child thread's return-value + let intermediate_sum = child.join().unwrap(); + intermediate_sums.push(intermediate_sum); + } + + // combine all intermediate sums into a single final sum. + // + // we use the "turbofish" ::<> to provide sum() with a type hint. + // + // TODO: try without the turbofish, by instead explicitly + // specifying the type of intermediate_sums + let final_result = intermediate_sums.iter().sum::(); + + println!("Final sum result: {}", final_result); +} + + +``` + +### Assignments +It is not wise to let our number of threads depend on user inputted data. +What if the user decides to insert a lot of spaces? Do we _really_ want to spawn 2,000 threads? +Modify the program so that the data is always chunked into a limited number of chunks, +defined by a static constant at the beginning of the program. + +### See also: +* [Threads][thread] +* [vectors][vectors] and [iterators][iterators] +* [closures][closures], [move][move] semantics and [`move` closures][move_closure] +* [destructuring][destructuring] assignments +* [turbofish notation][turbofish] to help type inference +* [unwrap vs. expect][unwrap] +* [enumerate][enumerate] + +[thread]: /std_misc/threads.html +[vectors]: /std/vec.html +[iterators]: /trait/iter.html +[destructuring]: https://doc.rust-lang.org/book/patterns.html#destructuring +[closures]: /fn/closures.html +[move]: /scope/move.html +[move_closure]: https://doc.rust-lang.org/book/closures.html#move-closures +[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect +[unwrap]: /error/option_unwrap.html +[enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate From d0b798f058ef2c19c8951f3dbbdd949378939263 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 18:56:32 -0400 Subject: [PATCH 0649/1122] chapter: scope --- examples/scope/borrow/alias/alias.rs | 50 ------------- examples/scope/borrow/alias/input.md | 6 -- examples/scope/borrow/borrow.rs | 35 --------- examples/scope/borrow/freeze/freeze.rs | 17 ----- examples/scope/borrow/freeze/input.md | 4 - examples/scope/borrow/input.md | 9 --- examples/scope/borrow/mut/input.md | 11 --- examples/scope/borrow/mut/mut.rs | 45 ----------- examples/scope/borrow/ref/input.md | 5 -- examples/scope/borrow/ref/ref.rs | 49 ------------ examples/scope/input.md | 3 - examples/scope/lifetime/elision/elision.rs | 25 ------- examples/scope/lifetime/elision/input.md | 15 ---- examples/scope/lifetime/explicit/explicit.rs | 33 --------- examples/scope/lifetime/explicit/input.md | 39 ---------- examples/scope/lifetime/fn/fn.rs | 42 ----------- examples/scope/lifetime/fn/input.md | 18 ----- examples/scope/lifetime/input.md | 17 ----- examples/scope/lifetime/lifetime.rs | 22 ------ .../scope/lifetime/lifetime_bounds/bounds.rs | 30 -------- .../scope/lifetime/lifetime_bounds/input.md | 20 ----- .../lifetime/lifetime_coercion/coercion.rs | 22 ------ .../scope/lifetime/lifetime_coercion/input.md | 6 -- examples/scope/lifetime/methods/input.md | 10 --- examples/scope/lifetime/methods/methods.rs | 16 ---- .../scope/lifetime/static_lifetime/input.md | 18 ----- .../static_lifetime/static_lifetime.rs | 31 -------- examples/scope/lifetime/struct/input.md | 10 --- examples/scope/lifetime/struct/struct.rs | 33 --------- examples/scope/move/input.md | 15 ---- examples/scope/move/move.rs | 42 ----------- examples/scope/move/mut/input.md | 3 - examples/scope/move/mut/mut.rs | 18 ----- examples/scope/raii/input.md | 39 ---------- examples/scope/raii/raii.rs | 28 ------- src/scope.md | 4 + src/scope/borrow.md | 46 ++++++++++++ src/scope/borrowing/alias.md | 58 +++++++++++++++ src/scope/borrowing/freeze.md | 23 ++++++ src/scope/borrowing/mut.md | 58 +++++++++++++++ src/scope/borrowing/ref.md | 56 ++++++++++++++ src/scope/lifetime.md | 41 ++++++++++ src/scope/lifetime/elision.md | 42 +++++++++++ src/scope/lifetime/explicit.md | 74 +++++++++++++++++++ src/scope/lifetime/fn.md | 62 ++++++++++++++++ src/scope/lifetime/lifetime_bounds.md | 52 +++++++++++++ src/scope/lifetime/lifetime_coercion.md | 30 ++++++++ src/scope/lifetime/methods.md | 27 +++++++ src/scope/lifetime/static_lifetime.md | 51 +++++++++++++ src/scope/lifetime/struct.md | 45 +++++++++++ src/scope/move.md | 59 +++++++++++++++ src/scope/move/mut.md | 23 ++++++ src/scope/raii.md | 69 +++++++++++++++++ 53 files changed, 820 insertions(+), 786 deletions(-) delete mode 100644 examples/scope/borrow/alias/alias.rs delete mode 100644 examples/scope/borrow/alias/input.md delete mode 100644 examples/scope/borrow/borrow.rs delete mode 100644 examples/scope/borrow/freeze/freeze.rs delete mode 100644 examples/scope/borrow/freeze/input.md delete mode 100644 examples/scope/borrow/input.md delete mode 100644 examples/scope/borrow/mut/input.md delete mode 100644 examples/scope/borrow/mut/mut.rs delete mode 100644 examples/scope/borrow/ref/input.md delete mode 100644 examples/scope/borrow/ref/ref.rs delete mode 100644 examples/scope/input.md delete mode 100644 examples/scope/lifetime/elision/elision.rs delete mode 100644 examples/scope/lifetime/elision/input.md delete mode 100644 examples/scope/lifetime/explicit/explicit.rs delete mode 100644 examples/scope/lifetime/explicit/input.md delete mode 100644 examples/scope/lifetime/fn/fn.rs delete mode 100644 examples/scope/lifetime/fn/input.md delete mode 100644 examples/scope/lifetime/input.md delete mode 100644 examples/scope/lifetime/lifetime.rs delete mode 100644 examples/scope/lifetime/lifetime_bounds/bounds.rs delete mode 100644 examples/scope/lifetime/lifetime_bounds/input.md delete mode 100644 examples/scope/lifetime/lifetime_coercion/coercion.rs delete mode 100644 examples/scope/lifetime/lifetime_coercion/input.md delete mode 100644 examples/scope/lifetime/methods/input.md delete mode 100644 examples/scope/lifetime/methods/methods.rs delete mode 100644 examples/scope/lifetime/static_lifetime/input.md delete mode 100644 examples/scope/lifetime/static_lifetime/static_lifetime.rs delete mode 100644 examples/scope/lifetime/struct/input.md delete mode 100644 examples/scope/lifetime/struct/struct.rs delete mode 100644 examples/scope/move/input.md delete mode 100644 examples/scope/move/move.rs delete mode 100644 examples/scope/move/mut/input.md delete mode 100644 examples/scope/move/mut/mut.rs delete mode 100644 examples/scope/raii/input.md delete mode 100644 examples/scope/raii/raii.rs diff --git a/examples/scope/borrow/alias/alias.rs b/examples/scope/borrow/alias/alias.rs deleted file mode 100644 index 5776e1fe24..0000000000 --- a/examples/scope/borrow/alias/alias.rs +++ /dev/null @@ -1,50 +0,0 @@ -struct Point { x: i32, y: i32, z: i32 } - -fn main() { - let mut point = Point { x: 0, y: 0, z: 0 }; - - { - let borrowed_point = &point; - let another_borrow = &point; - - // Data can be accessed via the references and the original owner - println!("Point has coordinates: ({}, {}, {})", - borrowed_point.x, another_borrow.y, point.z); - - // Error! Can't borrow point as mutable because it's currently - // borrowed as immutable. - //let mutable_borrow = &mut point; - // TODO ^ Try uncommenting this line - - // Immutable references go out of scope - } - - { - let mutable_borrow = &mut point; - - // Change data via mutable reference - mutable_borrow.x = 5; - mutable_borrow.y = 2; - mutable_borrow.z = 1; - - // Error! Can't borrow `point` as immutable because it's currently - // borrowed as mutable. - //let y = &point.y; - // TODO ^ Try uncommenting this line - - // Error! Can't print because `println!` takes an immutable reference. - //println!("Point Z coordinate is {}", point.z); - // TODO ^ Try uncommenting this line - - // Ok! Mutable references can be passed as immutable to `println!` - println!("Point has coordinates: ({}, {}, {})", - mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); - - // Mutable reference goes out of scope - } - - // Immutable references to point are allowed again - let borrowed_point = &point; - println!("Point now has coordinates: ({}, {}, {})", - borrowed_point.x, borrowed_point.y, borrowed_point.z); -} diff --git a/examples/scope/borrow/alias/input.md b/examples/scope/borrow/alias/input.md deleted file mode 100644 index 4016773eb9..0000000000 --- a/examples/scope/borrow/alias/input.md +++ /dev/null @@ -1,6 +0,0 @@ -Data can be immutably borrowed any number of times, but while immutably -borrowed, the original data can't be mutably borrowed. On the other hand, -only *one* mutable borrow is allowed at a time. The original data can be -borrowed again only *after* the mutable reference goes out of scope. - -{alias.play} diff --git a/examples/scope/borrow/borrow.rs b/examples/scope/borrow/borrow.rs deleted file mode 100644 index 53179805b7..0000000000 --- a/examples/scope/borrow/borrow.rs +++ /dev/null @@ -1,35 +0,0 @@ -// This function takes ownership of a box and destroys it -fn eat_box_i32(boxed_i32: Box) { - println!("Destroying box that contains {}", boxed_i32); -} - -// This function borrows an i32 -fn borrow_i32(borrowed_i32: &i32) { - println!("This int is: {}", borrowed_i32); -} - -fn main() { - // Create a boxed i32, and a stacked i32 - let boxed_i32 = Box::new(5_i32); - let stacked_i32 = 6_i32; - - // Borrow the contents of the box. Ownership is not taken, - // so the contents can be borrowed again. - borrow_i32(&boxed_i32); - borrow_i32(&stacked_i32); - - { - // Take a reference to the data contained inside the box - let _ref_to_i32: &i32 = &boxed_i32; - - // Error! - // Can't destroy `boxed_i32` while the inner value is borrowed. - eat_box_i32(boxed_i32); - // FIXME ^ Comment out this line - - // `_ref_to_i32` goes out of scope and is no longer borrowed. - } - - // `boxed_i32` can now give up ownership to `eat_box` and be destroyed - eat_box_i32(boxed_i32); -} diff --git a/examples/scope/borrow/freeze/freeze.rs b/examples/scope/borrow/freeze/freeze.rs deleted file mode 100644 index 42dcd8e79c..0000000000 --- a/examples/scope/borrow/freeze/freeze.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn main() { - let mut _mutable_integer = 7i32; - - { - // Borrow `_mutable_integer` - let _large_integer = &_mutable_integer; - - // Error! `_mutable_integer` is frozen in this scope - _mutable_integer = 50; - // FIXME ^ Comment out this line - - // `_large_integer` goes out of scope - } - - // Ok! `_mutable_integer` is not frozen in this scope - _mutable_integer = 3; -} diff --git a/examples/scope/borrow/freeze/input.md b/examples/scope/borrow/freeze/input.md deleted file mode 100644 index 9a57041c08..0000000000 --- a/examples/scope/borrow/freeze/input.md +++ /dev/null @@ -1,4 +0,0 @@ -When data is immutably borrowed, it also *freezes*. *Frozen* data can't be -modified via the original object until all references to it go out of scope: - -{freeze.play} diff --git a/examples/scope/borrow/input.md b/examples/scope/borrow/input.md deleted file mode 100644 index c9bd8265d2..0000000000 --- a/examples/scope/borrow/input.md +++ /dev/null @@ -1,9 +0,0 @@ -Most of the time, we'd like to access data without taking ownership over -it. To accomplish this, Rust uses a *borrowing* mechanism. Instead of -passing objects by-value (`T`), objects can be passed by reference (`&T`). - -The compiler statically guarantees (via its borrow checker) that references -*always* point to valid objects. That is, while references to an object -exist, the object cannot be destroyed. - -{borrow.play} diff --git a/examples/scope/borrow/mut/input.md b/examples/scope/borrow/mut/input.md deleted file mode 100644 index 1482aff079..0000000000 --- a/examples/scope/borrow/mut/input.md +++ /dev/null @@ -1,11 +0,0 @@ -Mutable data can be mutably borrowed using `&mut T`. This is called -a *mutable reference* and gives read/write access to the borrower. -In contrast, `&T` borrows the data via an immutable reference, and -the borrower can read the data but not modify it: - -{mut.play} - -### See also: -[`static`][static] - -[static]: ../lifetime/static_lifetime.html diff --git a/examples/scope/borrow/mut/mut.rs b/examples/scope/borrow/mut/mut.rs deleted file mode 100644 index 8c4399330d..0000000000 --- a/examples/scope/borrow/mut/mut.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[allow(dead_code)] -#[derive(Clone, Copy)] -struct Book { - // `&'static str` is a reference to a string allocated in read only memory - author: &'static str, - title: &'static str, - year: u32, -} - -// This function takes a reference to a book -fn borrow_book(book: &Book) { - println!("I immutably borrowed {} - {} edition", book.title, book.year); -} - -// This function takes a reference to a mutable book and changes `year` to 2014 -fn new_edition(book: &mut Book) { - book.year = 2014; - println!("I mutably borrowed {} - {} edition", book.title, book.year); -} - -fn main() { - // Create an immutable Book named `immutabook` - let immutabook = Book { - // string literals have type `&'static str` - author: "Douglas Hofstadter", - title: "Gödel, Escher, Bach", - year: 1979, - }; - - // Create a mutable copy of `immutabook` and call it `mutabook` - let mut mutabook = immutabook; - - // Immutably borrow an immutable object - borrow_book(&immutabook); - - // Immutably borrow a mutable object - borrow_book(&mutabook); - - // Borrow a mutable object as mutable - new_edition(&mut mutabook); - - // Error! Cannot borrow an immutable object as mutable - new_edition(&mut immutabook); - // FIXME ^ Comment out this line -} diff --git a/examples/scope/borrow/ref/input.md b/examples/scope/borrow/ref/input.md deleted file mode 100644 index d65deef065..0000000000 --- a/examples/scope/borrow/ref/input.md +++ /dev/null @@ -1,5 +0,0 @@ -When doing pattern matching or destructuring via the `let` binding, the `ref` -keyword can be used to take references to the fields of a struct/tuple. The -example below shows a few instances where this can be useful: - -{ref.play} diff --git a/examples/scope/borrow/ref/ref.rs b/examples/scope/borrow/ref/ref.rs deleted file mode 100644 index 2e8c07c3e9..0000000000 --- a/examples/scope/borrow/ref/ref.rs +++ /dev/null @@ -1,49 +0,0 @@ -#[derive(Clone, Copy)] -struct Point { x: i32, y: i32 } - -fn main() { - let c = 'Q'; - - // A `ref` borrow on the left side of an assignment is equivalent to - // an `&` borrow on the right side. - let ref ref_c1 = c; - let ref_c2 = &c; - - println!("ref_c1 equals ref_c2: {}", *ref_c1 == *ref_c2); - - let point = Point { x: 0, y: 0 }; - - // `ref` is also valid when destructuring a struct. - let _copy_of_x = { - // `ref_to_x` is a reference to the `x` field of `point`. - let Point { x: ref ref_to_x, y: _ } = point; - - // Return a copy of the `x` field of `point`. - *ref_to_x - }; - - // A mutable copy of `point` - let mut mutable_point = point; - - { - // `ref` can be paired with `mut` to take mutable references. - let Point { x: _, y: ref mut mut_ref_to_y } = mutable_point; - - // Mutate the `y` field of `mutable_point` via a mutable reference. - *mut_ref_to_y = 1; - } - - println!("point is ({}, {})", point.x, point.y); - println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); - - // A mutable tuple that includes a pointer - let mut mutable_tuple = (Box::new(5u32), 3u32); - - { - // Destructure `mutable_tuple` to change the value of `last`. - let (_, ref mut last) = mutable_tuple; - *last = 2u32; - } - - println!("tuple is {:?}", mutable_tuple); -} diff --git a/examples/scope/input.md b/examples/scope/input.md deleted file mode 100644 index db6a64dd1a..0000000000 --- a/examples/scope/input.md +++ /dev/null @@ -1,3 +0,0 @@ -Scopes play an important part in ownership, borrowing, and lifetimes. -That is, they indicate to the compiler when borrows are valid, when -resources can be freed, and when variables are created or destroyed. diff --git a/examples/scope/lifetime/elision/elision.rs b/examples/scope/lifetime/elision/elision.rs deleted file mode 100644 index cdf6b6a419..0000000000 --- a/examples/scope/lifetime/elision/elision.rs +++ /dev/null @@ -1,25 +0,0 @@ -// `elided_input` and `annotated_input` essentially have identical signatures -// because the lifetime of `elided_input` is elided by the compiler: -fn elided_input(x: &i32) { - println!("`elided_input`: {}", x) -} - -fn annotated_input<'a>(x: &'a i32) { - println!("`annotated_input`: {}", x) -} - -// Similarly, `elided_pass` and `annotated_pass` have identical signatures -// because the lifetime is added implicitly to `elided_pass`: -fn elided_pass(x: &i32) -> &i32 { x } - -fn annotated_pass<'a>(x: &'a i32) -> &'a i32 { x } - -fn main() { - let x = 3; - - elided_input(&x); - annotated_input(&x); - - println!("`elided_pass`: {}", elided_pass(&x)); - println!("`annotated_pass`: {}", annotated_pass(&x)); -} diff --git a/examples/scope/lifetime/elision/input.md b/examples/scope/lifetime/elision/input.md deleted file mode 100644 index f153585c5a..0000000000 --- a/examples/scope/lifetime/elision/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Some lifetime patterns are overwelmingly common and so the borrow checker -will implicitly add them to save typing and to improve readability. -This process of implicit addition is called elision. Elision exists in Rust -solely because these patterns are common. - -The following code shows a few examples of elision. For a more comprehensive -description of elision, see [lifetime elision][elision] in the book. - -{elision.play} - -### See also: - -[elision][elision] - -[elision]: https://doc.rust-lang.org/book/lifetimes.html#lifetime-elision diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs deleted file mode 100644 index 380f447a49..0000000000 --- a/examples/scope/lifetime/explicit/explicit.rs +++ /dev/null @@ -1,33 +0,0 @@ -// `print_refs` takes two references to `i32` which have different -// lifetimes `'a` and `'b`. These two lifetimes must both be at -// least as long as the function `print_refs`. -fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { - println!("x is {} and y is {}", x, y); -} - -// A function which takes no arguments, but has a lifetime parameter `'a`. -fn failed_borrow<'a>() { - let _x = 12; - - // ERROR: `_x` does not live long enough - //let y: &'a i32 = &_x; - // Attempting to use the lifetime `'a` as an explicit type annotation - // inside the function will fail because the lifetime of `&_x` is shorter - // than that of `y`. A short lifetime cannot be coerced into a longer one. -} - -fn main() { - // Create variables to be borrowed below. - let (four, nine) = (4, 9); - - // Borrows (`&`) of both variables are passed into the function. - print_refs(&four, &nine); - // Any input which is borrowed must outlive the borrower. - // In other words, the lifetime of `four` and `nine` must - // be longer than that of `print_refs`. - - failed_borrow(); - // `failed_borrow` contains no references to force `'a` to be - // longer than the lifetime of the function, but `'a` is longer. - // Because the lifetime is never constrained, it defaults to `'static`. -} diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md deleted file mode 100644 index 60acf365c6..0000000000 --- a/examples/scope/lifetime/explicit/input.md +++ /dev/null @@ -1,39 +0,0 @@ -The borrow checker uses explicit lifetime annotations to determine -how long references should be valid. In cases where lifetimes are not -elided[^1], Rust requires explicit annotations to determine what the -lifetime of a reference should be. The syntax for explicitly annotating -a lifetime uses an apostrophe character as follows: - -```rust -foo<'a> -// `foo` has a lifetime parameter `'a` -``` - -Similar to [closures][anonymity], using lifetimes requires generics. -Additionally, this lifetime syntax indicates that the lifetime of `foo` -may not exceed that of `'a`. Explicit annotation of a type has the form -`&'a T` where `'a` has already been introduced. - -In cases with multiple lifetimes, the syntax is similar: - -```rust -foo<'a, 'b> -// `foo` has lifetime parameters `'a` and `'b` -``` - -In this case, the lifetime of `foo` cannot exceed that of either `'a` *or* `'b`. - -See the following example for explicit lifetime annotation in use: - -{explicit.play} - -[^1]: [elision][elision] implicitly annotates lifetimes and so is different. - -### See also: - -[generics][generics] and [closures][closures] - -[anonymity]: /fn/closures/anonymity.html -[closures]: /fn/closures.html -[elision]: /scope/lifetime/elision.html -[generics]: /generics.html diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs deleted file mode 100644 index 5aafc4c942..0000000000 --- a/examples/scope/lifetime/fn/fn.rs +++ /dev/null @@ -1,42 +0,0 @@ -// One input reference with lifetime `'a` which must live -// at least as long as the function. -fn print_one<'a>(x: &'a i32) { - println!("`print_one`: x is {}", x); -} - -// Mutable references are possible with lifetimes as well. -fn add_one<'a>(x: &'a mut i32) { - *x += 1; -} - -// Multiple elements with different lifetimes. In this case, it -// would be fine for both to have the same lifetime `'a`, but -// in more complex cases, different lifetimes may be required. -fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { - println!("`print_multi`: x is {}, y is {}", x, y); -} - -// Returning references that have been passed in is acceptable. -// However, the correct lifetime must be returned. -fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } - -//fn invalid_output<'a>() -> &'a i32 { &7 } -// The above is invalid: `'a` must live longer than the function. -// Here, `&7` would create an `i32`, followed by a reference. -// Then the data is dropped upon exiting the scope, leaving -// a reference to invalid data to be returned. - -fn main() { - let x = 7; - let y = 9; - - print_one(&x); - print_multi(&x, &y); - - let z = pass_x(&x, &y); - print_one(z); - - let mut t = 3; - add_one(&mut t); - print_one(&t); -} diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md deleted file mode 100644 index b37ec0dfdb..0000000000 --- a/examples/scope/lifetime/fn/input.md +++ /dev/null @@ -1,18 +0,0 @@ -Ignoring [elision], function signatures with lifetimes have a few constraints: - -* any reference *must* have an annotated lifetime. -* any reference being returned *must* have the same lifetime as an input or -be `static`. - -Additionally, note that returning references without input is banned if it -would result in returning references to invalid data. The following example shows -off some valid forms of functions with lifetimes: - -{fn.play} - -### See also: - -[functions][fn] - -[elision]: /scope/lifetime/elision.html -[fn]: /fn.html diff --git a/examples/scope/lifetime/input.md b/examples/scope/lifetime/input.md deleted file mode 100644 index 6a39515ff6..0000000000 --- a/examples/scope/lifetime/input.md +++ /dev/null @@ -1,17 +0,0 @@ -A *lifetime* is a construct the compiler (also called the borrow checker) -uses to ensure all borrows are valid. Specifically, a variable's lifetime -begins when it is created and ends when it is destroyed. While lifetimes -and scopes are often referred to together, they are not the same. - -Take, for example, the case where we borrow a variable via `&`. The -borrow has a lifetime that is determined by where it is declared. As a result, -the borrow is valid as long as it ends before the lender is destroyed. However, -the scope of the borrow is determined by where the reference is used. - -In the following example and in the rest of this section, we will see how -lifetimes relate to scopes, as well as how the two differ. - -{lifetime.play} - -Note that no names or types are assigned to label lifetimes. -This restricts how lifetimes will be able to be used as we will see. diff --git a/examples/scope/lifetime/lifetime.rs b/examples/scope/lifetime/lifetime.rs deleted file mode 100644 index 501572c2a6..0000000000 --- a/examples/scope/lifetime/lifetime.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Lifetimes are annotated below with lines denoting the creation -// and destruction of each variable. -// `i` has the longest lifetime because its scope entirely encloses -// both `borrow1` and `borrow2`. The duration of `borrow1` compared -// to `borrow2` is irrelevant since they are disjoint. -fn main() { - let i = 3; // Lifetime for `i` starts. ────────────────┐ - // │ - { // │ - let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ - // ││ - println!("borrow1: {}", borrow1); // ││ - } // `borrow1 ends. ──────────────────────────────────┘│ - // │ - // │ - { // │ - let borrow2 = &i; // `borrow2` lifetime starts. ──┐│ - // ││ - println!("borrow2: {}", borrow2); // ││ - } // `borrow2` ends. ─────────────────────────────────┘│ - // │ -} // Lifetime ends. ─────────────────────────────────────┘ diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs deleted file mode 100644 index 42485cb038..0000000000 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::fmt::Debug; // Trait to bound with. - -#[derive(Debug)] -struct Ref<'a, T: 'a>(&'a T); -// `Ref` contains a reference to a generic type `T` that has -// an unknown lifetime `'a`. `T` is bounded such that any -// *references* in `T` must outlive `'a`. Additionally, the lifetime -// of `Ref` may not exceed `'a`. - -// A generic function which prints using the `Debug` trait. -fn print(t: T) where - T: Debug { - println!("`print`: t is {:?}", t); -} - -// Here a reference to `T` is taken where `T` implements -// `Debug` and all *references* in `T` outlive `'a`. In -// addition, `'a` must outlive the function. -fn print_ref<'a, T>(t: &'a T) where - T: Debug + 'a { - println!("`print_ref`: t is {:?}", t); -} - -fn main() { - let x = 7; - let ref_x = Ref(&x); - - print_ref(&ref_x); - print(ref_x); -} diff --git a/examples/scope/lifetime/lifetime_bounds/input.md b/examples/scope/lifetime/lifetime_bounds/input.md deleted file mode 100644 index fd6a0a95c3..0000000000 --- a/examples/scope/lifetime/lifetime_bounds/input.md +++ /dev/null @@ -1,20 +0,0 @@ -Just like generic types can be bounded, lifetimes (themselves generic) -use bounds as well. The `:` character has a slightly different meaning here, -but `+` is the same. Note how the following read: - -1. `T: 'a`: *All* references in `T` must outlive lifetime `'a`. -2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references -in `T` must outlive `'a`. - -The example below shows the above syntax in action: - -{bounds.play} - -### See also: - -[generics][generics], [bounds in generics][bounds], and -[multiple bounds in generics][multibounds] - -[generics]: /generics.html -[bounds]: /generics/bounds.html -[multibounds]: /generics/multi_bounds.html \ No newline at end of file diff --git a/examples/scope/lifetime/lifetime_coercion/coercion.rs b/examples/scope/lifetime/lifetime_coercion/coercion.rs deleted file mode 100644 index a8fc0a3a0f..0000000000 --- a/examples/scope/lifetime/lifetime_coercion/coercion.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Here, Rust infers a lifetime that is as short as possible. -// The two references are then coerced to that lifetime. -fn multiply<'a>(first: &'a i32, second: &'a i32) -> i32 { - first * second -} - -// `<'a: 'b, 'b>` reads as lifetime `'a` is at least as long as `'b`. -// Here, we take in an `&'a i32` and return a `&'b i32` as a result of coercion. -fn choose_first<'a: 'b, 'b>(first: &'a i32, _: &'b i32) -> &'b i32 { - first -} - -fn main() { - let first = 2; // Longer lifetime - - { - let second = 3; // Shorter lifetime - - println!("The product is {}", multiply(&first, &second)); - println!("{} is the first", choose_first(&first, &second)); - }; -} diff --git a/examples/scope/lifetime/lifetime_coercion/input.md b/examples/scope/lifetime/lifetime_coercion/input.md deleted file mode 100644 index c96a84c2fd..0000000000 --- a/examples/scope/lifetime/lifetime_coercion/input.md +++ /dev/null @@ -1,6 +0,0 @@ -A longer lifetime can be coerced into a shorter one -so that it works inside a scope it normally wouldn't work in. -This comes in the form of inferred coercion by the Rust compiler, -and also in the form of declaring a lifetime difference: - -{coercion.play} diff --git a/examples/scope/lifetime/methods/input.md b/examples/scope/lifetime/methods/input.md deleted file mode 100644 index ffb8279b02..0000000000 --- a/examples/scope/lifetime/methods/input.md +++ /dev/null @@ -1,10 +0,0 @@ -Methods are annotated similarly to functions: - -{methods.play} - -### See also: - -[methods][methods] - - -[methods]: /fn/methods.html diff --git a/examples/scope/lifetime/methods/methods.rs b/examples/scope/lifetime/methods/methods.rs deleted file mode 100644 index 95915b3c6c..0000000000 --- a/examples/scope/lifetime/methods/methods.rs +++ /dev/null @@ -1,16 +0,0 @@ -struct Owner(i32); - -impl Owner { - // Annotate lifetimes as in a standalone function. - fn add_one<'a>(&'a mut self) { self.0 += 1; } - fn print<'a>(&'a self) { - println!("`print`: {}", self.0); - } -} - -fn main() { - let mut owner = Owner(18); - - owner.add_one(); - owner.print(); -} diff --git a/examples/scope/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md deleted file mode 100644 index 95f4fd9046..0000000000 --- a/examples/scope/lifetime/static_lifetime/input.md +++ /dev/null @@ -1,18 +0,0 @@ -A `'static` lifetime is the longest possible lifetime, and lasts for -the lifetime of the running program. A `'static` lifetime may also be -coerced to a shorter lifetime. There are two ways to make a variable -with `'static` lifetime, and both are stored in the read-only memory -of the binary: - -* Make a constant with the `static` declaration. -* Make a `string` literal which has type: `&'static str`. - -See the following example for a display of each method: - -{static_lifetime.play} - -### See also: - -[`'static` constants][static_const] - -[static_const]: /custom_types/constants.html diff --git a/examples/scope/lifetime/static_lifetime/static_lifetime.rs b/examples/scope/lifetime/static_lifetime/static_lifetime.rs deleted file mode 100644 index 8ba00db2c6..0000000000 --- a/examples/scope/lifetime/static_lifetime/static_lifetime.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Make a constant with `'static` lifetime. -static NUM: i32 = 18; - -// Returns a reference to `NUM` where its `'static` -// lifetime is coerced to that of the input argument. -fn coerce_static<'a>(_: &'a i32) -> &'a i32 { - &NUM -} - -fn main() { - { - // Make a `string` literal and print it: - let static_string = "I'm in read-only memory"; - println!("static_string: {}", static_string); - - // When `static_string` goes out of scope, the reference - // can no longer be used, but the data remains in the binary. - } - - { - // Make an integer to use for `coerce_static`: - let lifetime_num = 9; - - // Coerce `NUM` to lifetime of `lifetime_num`: - let coerced_static = coerce_static(&lifetime_num); - - println!("coerced_static: {}", coerced_static); - } - - println!("NUM: {} stays accessible!", NUM); -} diff --git a/examples/scope/lifetime/struct/input.md b/examples/scope/lifetime/struct/input.md deleted file mode 100644 index 496e989f9f..0000000000 --- a/examples/scope/lifetime/struct/input.md +++ /dev/null @@ -1,10 +0,0 @@ -Annotation of lifetimes in structures are also similar to functions: - -{struct.play} - -### See also: - -[`structs`][structs] - - -[structs]: /custom_types/structs.html diff --git a/examples/scope/lifetime/struct/struct.rs b/examples/scope/lifetime/struct/struct.rs deleted file mode 100644 index f7e057a9f3..0000000000 --- a/examples/scope/lifetime/struct/struct.rs +++ /dev/null @@ -1,33 +0,0 @@ -// A type `Borrowed` which houses a reference to an -// `i32`. The reference to `i32` must outlive `Borrowed`. -#[derive(Debug)] -struct Borrowed<'a>(&'a i32); - -// Similarly, both references here must outlive this structure. -#[derive(Debug)] -struct NamedBorrowed<'a> { - x: &'a i32, - y: &'a i32, -} - -// An enum which is either an `i32` or a reference to one. -#[derive(Debug)] -enum Either<'a> { - Num(i32), - Ref(&'a i32), -} - -fn main() { - let x = 18; - let y = 15; - - let single = Borrowed(&x); - let double = NamedBorrowed { x: &x, y: &y }; - let reference = Either::Ref(&x); - let number = Either::Num(y); - - println!("x is borrowed in {:?}", single); - println!("x and y are borrowed in {:?}", double); - println!("x is borrowed in {:?}", reference); - println!("y is *not* borrowed in {:?}", number); -} diff --git a/examples/scope/move/input.md b/examples/scope/move/input.md deleted file mode 100644 index b5c2259019..0000000000 --- a/examples/scope/move/input.md +++ /dev/null @@ -1,15 +0,0 @@ -Because variables are in charge of freeing their own resources, -**resources can only have one owner**. This also prevents resources -from being freed more than once. Note that not all variables own -resources (e.g. [references]). - -When doing assignments (`let x = y`) or passing function arguments by value -(`foo(x)`), the *ownership* of the resources is transferred. In Rust-speak, -this is known as a *move*. - -After moving resources, the previous owner can no longer be used. This avoids -creating dangling pointers. - -{move.play} - -[references]: /flow_control/match/destructuring/destructure_pointers.html diff --git a/examples/scope/move/move.rs b/examples/scope/move/move.rs deleted file mode 100644 index efdd5e264f..0000000000 --- a/examples/scope/move/move.rs +++ /dev/null @@ -1,42 +0,0 @@ -// This function takes ownership of the heap allocated memory -fn destroy_box(c: Box) { - println!("Destroying a box that contains {}", c); - - // `c` is destroyed and the memory freed -} - -fn main() { - // _Stack_ allocated integer - let x = 5u32; - - // *Copy* `x` into `y` - no resources are moved - let y = x; - - // Both values can be independently used - println!("x is {}, and y is {}", x, y); - - // `a` is a pointer to a _heap_ allocated integer - let a = Box::new(5i32); - - println!("a contains: {}", a); - - // *Move* `a` into `b` - let b = a; - // The pointer address of `a` is copied (not the data) into `b`. - // Both are now pointers to the same heap allocated data, but - // `b` now owns it. - - // Error! `a` can no longer access the data, because it no longer owns the - // heap memory - //println!("a contains: {}", a); - // TODO ^ Try uncommenting this line - - // This function takes ownership of the heap allocated memory from `b` - destroy_box(b); - - // Since the heap memory has been freed at this point, this action would - // result in dereferencing freed memory, but it's forbidden by the compiler - // Error! Same reason as the previous Error - //println!("b contains: {}", b); - // TODO ^ Try uncommenting this line -} diff --git a/examples/scope/move/mut/input.md b/examples/scope/move/mut/input.md deleted file mode 100644 index 239187aa28..0000000000 --- a/examples/scope/move/mut/input.md +++ /dev/null @@ -1,3 +0,0 @@ -Mutability of data can be changed when ownership is transferred. - -{mut.play} diff --git a/examples/scope/move/mut/mut.rs b/examples/scope/move/mut/mut.rs deleted file mode 100644 index f9346467fa..0000000000 --- a/examples/scope/move/mut/mut.rs +++ /dev/null @@ -1,18 +0,0 @@ -fn main() { - let immutable_box = Box::new(5u32); - - println!("immutable_box contains {}", immutable_box); - - // Mutability error - //*immutable_box = 4; - - // *Move* the box, changing the ownership (and mutability) - let mut mutable_box = immutable_box; - - println!("mutable_box contains {}", mutable_box); - - // Modify the contents of the box - *mutable_box = 4; - - println!("mutable_box now contains {}", mutable_box); -} diff --git a/examples/scope/raii/input.md b/examples/scope/raii/input.md deleted file mode 100644 index 0a8fd71488..0000000000 --- a/examples/scope/raii/input.md +++ /dev/null @@ -1,39 +0,0 @@ -Variables in Rust do more than just hold data in the stack: they also *own* -resources, e.g. `Box` owns memory in the heap. Rust enforces [RAII][raii] -(Resource Acquisition Is Initialization), so whenever an object goes out of -scope, its destructor is called and its owned resources are freed. - -This behavior shields against *resource leak* bugs, so you'll never have to -manually free memory or worry about memory leaks again! Here's a quick showcase: - -{raii.play} - -Of course, we can double check for memory errors using [`valgrind`][valgrind]: - -``` -$ rustc raii.rs && valgrind ./raii -==26873== Memcheck, a memory error detector -==26873== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. -==26873== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info -==26873== Command: ./raii -==26873== -==26873== -==26873== HEAP SUMMARY: -==26873== in use at exit: 0 bytes in 0 blocks -==26873== total heap usage: 1,013 allocs, 1,013 frees, 8,696 bytes allocated -==26873== -==26873== All heap blocks were freed -- no leaks are possible -==26873== -==26873== For counts of detected and suppressed errors, rerun with: -v -==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) -``` - -No leaks here! - -### See also: - -[Box][box] - -[raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization -[box]: /std/box.html -[valgrind]: http://valgrind.org/info/ \ No newline at end of file diff --git a/examples/scope/raii/raii.rs b/examples/scope/raii/raii.rs deleted file mode 100644 index 919dda5fc2..0000000000 --- a/examples/scope/raii/raii.rs +++ /dev/null @@ -1,28 +0,0 @@ -// raii.rs -fn create_box() { - // Allocate an integer on the heap - let _box1 = Box::new(3i32); - - // `_box1` is destroyed here, and memory gets freed -} - -fn main() { - // Allocate an integer on the heap - let _box2 = Box::new(5i32); - - // A nested scope: - { - // Allocate an integer on the heap - let _box3 = Box::new(4i32); - - // `_box3` is destroyed here, and memory gets freed - } - - // Creating lots of boxes just for fun - // There's no need to manually free memory! - for _ in 0u32..1_000 { - create_box(); - } - - // `_box2` is destroyed here, and memory gets freed -} diff --git a/src/scope.md b/src/scope.md index 1b7c55ad2d..ac70132781 100644 --- a/src/scope.md +++ b/src/scope.md @@ -1 +1,5 @@ # Scoping rules + +Scopes play an important part in ownership, borrowing, and lifetimes. +That is, they indicate to the compiler when borrows are valid, when +resources can be freed, and when variables are created or destroyed. \ No newline at end of file diff --git a/src/scope/borrow.md b/src/scope/borrow.md index dda14f3782..59a655fc0b 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -1 +1,47 @@ # Borrowing + +Most of the time, we'd like to access data without taking ownership over +it. To accomplish this, Rust uses a *borrowing* mechanism. Instead of +passing objects by-value (`T`), objects can be passed by reference (`&T`). + +The compiler statically guarantees (via its borrow checker) that references +*always* point to valid objects. That is, while references to an object +exist, the object cannot be destroyed. + +```rust,editable +// This function takes ownership of a box and destroys it +fn eat_box_i32(boxed_i32: Box) { + println!("Destroying box that contains {}", boxed_i32); +} + +// This function borrows an i32 +fn borrow_i32(borrowed_i32: &i32) { + println!("This int is: {}", borrowed_i32); +} + +fn main() { + // Create a boxed i32, and a stacked i32 + let boxed_i32 = Box::new(5_i32); + let stacked_i32 = 6_i32; + + // Borrow the contents of the box. Ownership is not taken, + // so the contents can be borrowed again. + borrow_i32(&boxed_i32); + borrow_i32(&stacked_i32); + + { + // Take a reference to the data contained inside the box + let _ref_to_i32: &i32 = &boxed_i32; + + // Error! + // Can't destroy `boxed_i32` while the inner value is borrowed. + eat_box_i32(boxed_i32); + // FIXME ^ Comment out this line + + // `_ref_to_i32` goes out of scope and is no longer borrowed. + } + + // `boxed_i32` can now give up ownership to `eat_box` and be destroyed + eat_box_i32(boxed_i32); +} +``` \ No newline at end of file diff --git a/src/scope/borrowing/alias.md b/src/scope/borrowing/alias.md index 81497a63e9..dc26d4c1af 100644 --- a/src/scope/borrowing/alias.md +++ b/src/scope/borrowing/alias.md @@ -1 +1,59 @@ # Aliasing + +Data can be immutably borrowed any number of times, but while immutably +borrowed, the original data can't be mutably borrowed. On the other hand, +only *one* mutable borrow is allowed at a time. The original data can be +borrowed again only *after* the mutable reference goes out of scope. + +```rust,editable +struct Point { x: i32, y: i32, z: i32 } + +fn main() { + let mut point = Point { x: 0, y: 0, z: 0 }; + + { + let borrowed_point = &point; + let another_borrow = &point; + + // Data can be accessed via the references and the original owner + println!("Point has coordinates: ({}, {}, {})", + borrowed_point.x, another_borrow.y, point.z); + + // Error! Can't borrow point as mutable because it's currently + // borrowed as immutable. + //let mutable_borrow = &mut point; + // TODO ^ Try uncommenting this line + + // Immutable references go out of scope + } + + { + let mutable_borrow = &mut point; + + // Change data via mutable reference + mutable_borrow.x = 5; + mutable_borrow.y = 2; + mutable_borrow.z = 1; + + // Error! Can't borrow `point` as immutable because it's currently + // borrowed as mutable. + //let y = &point.y; + // TODO ^ Try uncommenting this line + + // Error! Can't print because `println!` takes an immutable reference. + //println!("Point Z coordinate is {}", point.z); + // TODO ^ Try uncommenting this line + + // Ok! Mutable references can be passed as immutable to `println!` + println!("Point has coordinates: ({}, {}, {})", + mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); + + // Mutable reference goes out of scope + } + + // Immutable references to point are allowed again + let borrowed_point = &point; + println!("Point now has coordinates: ({}, {}, {})", + borrowed_point.x, borrowed_point.y, borrowed_point.z); +} +``` \ No newline at end of file diff --git a/src/scope/borrowing/freeze.md b/src/scope/borrowing/freeze.md index 1873d01d8e..e3123b6df5 100644 --- a/src/scope/borrowing/freeze.md +++ b/src/scope/borrowing/freeze.md @@ -1 +1,24 @@ # Freezing + +When data is immutably borrowed, it also *freezes*. *Frozen* data can't be +modified via the original object until all references to it go out of scope: + +```rust,editable +fn main() { + let mut _mutable_integer = 7i32; + + { + // Borrow `_mutable_integer` + let _large_integer = &_mutable_integer; + + // Error! `_mutable_integer` is frozen in this scope + _mutable_integer = 50; + // FIXME ^ Comment out this line + + // `_large_integer` goes out of scope + } + + // Ok! `_mutable_integer` is not frozen in this scope + _mutable_integer = 3; +} +``` \ No newline at end of file diff --git a/src/scope/borrowing/mut.md b/src/scope/borrowing/mut.md index b2197b1cec..82444d5f8a 100644 --- a/src/scope/borrowing/mut.md +++ b/src/scope/borrowing/mut.md @@ -1 +1,59 @@ # Mutability + +Mutable data can be mutably borrowed using `&mut T`. This is called +a *mutable reference* and gives read/write access to the borrower. +In contrast, `&T` borrows the data via an immutable reference, and +the borrower can read the data but not modify it: + +```rust,editable +#[allow(dead_code)] +#[derive(Clone, Copy)] +struct Book { + // `&'static str` is a reference to a string allocated in read only memory + author: &'static str, + title: &'static str, + year: u32, +} + +// This function takes a reference to a book +fn borrow_book(book: &Book) { + println!("I immutably borrowed {} - {} edition", book.title, book.year); +} + +// This function takes a reference to a mutable book and changes `year` to 2014 +fn new_edition(book: &mut Book) { + book.year = 2014; + println!("I mutably borrowed {} - {} edition", book.title, book.year); +} + +fn main() { + // Create an immutable Book named `immutabook` + let immutabook = Book { + // string literals have type `&'static str` + author: "Douglas Hofstadter", + title: "Gödel, Escher, Bach", + year: 1979, + }; + + // Create a mutable copy of `immutabook` and call it `mutabook` + let mut mutabook = immutabook; + + // Immutably borrow an immutable object + borrow_book(&immutabook); + + // Immutably borrow a mutable object + borrow_book(&mutabook); + + // Borrow a mutable object as mutable + new_edition(&mut mutabook); + + // Error! Cannot borrow an immutable object as mutable + new_edition(&mut immutabook); + // FIXME ^ Comment out this line +} +``` + +### See also: +[`static`][static] + +[static]: ../lifetime/static_lifetime.html diff --git a/src/scope/borrowing/ref.md b/src/scope/borrowing/ref.md index eda4649c45..3c035f64c0 100644 --- a/src/scope/borrowing/ref.md +++ b/src/scope/borrowing/ref.md @@ -1 +1,57 @@ # The ref pattern + +When doing pattern matching or destructuring via the `let` binding, the `ref` +keyword can be used to take references to the fields of a struct/tuple. The +example below shows a few instances where this can be useful: + +```rust,editable +#[derive(Clone, Copy)] +struct Point { x: i32, y: i32 } + +fn main() { + let c = 'Q'; + + // A `ref` borrow on the left side of an assignment is equivalent to + // an `&` borrow on the right side. + let ref ref_c1 = c; + let ref_c2 = &c; + + println!("ref_c1 equals ref_c2: {}", *ref_c1 == *ref_c2); + + let point = Point { x: 0, y: 0 }; + + // `ref` is also valid when destructuring a struct. + let _copy_of_x = { + // `ref_to_x` is a reference to the `x` field of `point`. + let Point { x: ref ref_to_x, y: _ } = point; + + // Return a copy of the `x` field of `point`. + *ref_to_x + }; + + // A mutable copy of `point` + let mut mutable_point = point; + + { + // `ref` can be paired with `mut` to take mutable references. + let Point { x: _, y: ref mut mut_ref_to_y } = mutable_point; + + // Mutate the `y` field of `mutable_point` via a mutable reference. + *mut_ref_to_y = 1; + } + + println!("point is ({}, {})", point.x, point.y); + println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); + + // A mutable tuple that includes a pointer + let mut mutable_tuple = (Box::new(5u32), 3u32); + + { + // Destructure `mutable_tuple` to change the value of `last`. + let (_, ref mut last) = mutable_tuple; + *last = 2u32; + } + + println!("tuple is {:?}", mutable_tuple); +} +``` \ No newline at end of file diff --git a/src/scope/lifetime.md b/src/scope/lifetime.md index 130cd9f700..67c8ea6147 100644 --- a/src/scope/lifetime.md +++ b/src/scope/lifetime.md @@ -1 +1,42 @@ # Lifetimes + +A *lifetime* is a construct the compiler (also called the borrow checker) +uses to ensure all borrows are valid. Specifically, a variable's lifetime +begins when it is created and ends when it is destroyed. While lifetimes +and scopes are often referred to together, they are not the same. + +Take, for example, the case where we borrow a variable via `&`. The +borrow has a lifetime that is determined by where it is declared. As a result, +the borrow is valid as long as it ends before the lender is destroyed. However, +the scope of the borrow is determined by where the reference is used. + +In the following example and in the rest of this section, we will see how +lifetimes relate to scopes, as well as how the two differ. + +```rust,editable +// Lifetimes are annotated below with lines denoting the creation +// and destruction of each variable. +// `i` has the longest lifetime because its scope entirely encloses +// both `borrow1` and `borrow2`. The duration of `borrow1` compared +// to `borrow2` is irrelevant since they are disjoint. +fn main() { + let i = 3; // Lifetime for `i` starts. ────────────────┐ + // │ + { // │ + let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ + // ││ + println!("borrow1: {}", borrow1); // ││ + } // `borrow1 ends. ──────────────────────────────────┘│ + // │ + // │ + { // │ + let borrow2 = &i; // `borrow2` lifetime starts. ──┐│ + // ││ + println!("borrow2: {}", borrow2); // ││ + } // `borrow2` ends. ─────────────────────────────────┘│ + // │ +} // Lifetime ends. ─────────────────────────────────────┘ +``` + +Note that no names or types are assigned to label lifetimes. +This restricts how lifetimes will be able to be used as we will see. diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index 3348a5b7f5..1fa3fc25ee 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -1 +1,43 @@ # elision + +Some lifetime patterns are overwelmingly common and so the borrow checker +will implicitly add them to save typing and to improve readability. +This process of implicit addition is called elision. Elision exists in Rust +solely because these patterns are common. + +The following code shows a few examples of elision. For a more comprehensive +description of elision, see [lifetime elision][elision] in the book. + +```rust,editable +// `elided_input` and `annotated_input` essentially have identical signatures +// because the lifetime of `elided_input` is elided by the compiler: +fn elided_input(x: &i32) { + println!("`elided_input`: {}", x) +} + +fn annotated_input<'a>(x: &'a i32) { + println!("`annotated_input`: {}", x) +} + +// Similarly, `elided_pass` and `annotated_pass` have identical signatures +// because the lifetime is added implicitly to `elided_pass`: +fn elided_pass(x: &i32) -> &i32 { x } + +fn annotated_pass<'a>(x: &'a i32) -> &'a i32 { x } + +fn main() { + let x = 3; + + elided_input(&x); + annotated_input(&x); + + println!("`elided_pass`: {}", elided_pass(&x)); + println!("`annotated_pass`: {}", annotated_pass(&x)); +} +``` + +### See also: + +[elision][elision] + +[elision]: https://doc.rust-lang.org/book/lifetimes.html#lifetime-elision diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md index c24b3d69c9..a934900033 100644 --- a/src/scope/lifetime/explicit.md +++ b/src/scope/lifetime/explicit.md @@ -1 +1,75 @@ # Explicit annotation + +The borrow checker uses explicit lifetime annotations to determine +how long references should be valid. In cases where lifetimes are not +elided[^1], Rust requires explicit annotations to determine what the +lifetime of a reference should be. The syntax for explicitly annotating +a lifetime uses an apostrophe character as follows: + +```rust +foo<'a> +// `foo` has a lifetime parameter `'a` +``` + +Similar to [closures][anonymity], using lifetimes requires generics. +Additionally, this lifetime syntax indicates that the lifetime of `foo` +may not exceed that of `'a`. Explicit annotation of a type has the form +`&'a T` where `'a` has already been introduced. + +In cases with multiple lifetimes, the syntax is similar: + +```rust +foo<'a, 'b> +// `foo` has lifetime parameters `'a` and `'b` +``` + +In this case, the lifetime of `foo` cannot exceed that of either `'a` *or* `'b`. + +See the following example for explicit lifetime annotation in use: + +```rust,editable +// `print_refs` takes two references to `i32` which have different +// lifetimes `'a` and `'b`. These two lifetimes must both be at +// least as long as the function `print_refs`. +fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { + println!("x is {} and y is {}", x, y); +} + +// A function which takes no arguments, but has a lifetime parameter `'a`. +fn failed_borrow<'a>() { + let _x = 12; + + // ERROR: `_x` does not live long enough + //let y: &'a i32 = &_x; + // Attempting to use the lifetime `'a` as an explicit type annotation + // inside the function will fail because the lifetime of `&_x` is shorter + // than that of `y`. A short lifetime cannot be coerced into a longer one. +} + +fn main() { + // Create variables to be borrowed below. + let (four, nine) = (4, 9); + + // Borrows (`&`) of both variables are passed into the function. + print_refs(&four, &nine); + // Any input which is borrowed must outlive the borrower. + // In other words, the lifetime of `four` and `nine` must + // be longer than that of `print_refs`. + + failed_borrow(); + // `failed_borrow` contains no references to force `'a` to be + // longer than the lifetime of the function, but `'a` is longer. + // Because the lifetime is never constrained, it defaults to `'static`. +} +``` + +[^1]: [elision][elision] implicitly annotates lifetimes and so is different. + +### See also: + +[generics][generics] and [closures][closures] + +[anonymity]: /fn/closures/anonymity.html +[closures]: /fn/closures.html +[elision]: /scope/lifetime/elision.html +[generics]: /generics.html diff --git a/src/scope/lifetime/fn.md b/src/scope/lifetime/fn.md index 0c5faf50f8..8b061ab537 100644 --- a/src/scope/lifetime/fn.md +++ b/src/scope/lifetime/fn.md @@ -1 +1,63 @@ # Functions + +Ignoring [elision], function signatures with lifetimes have a few constraints: + +* any reference *must* have an annotated lifetime. +* any reference being returned *must* have the same lifetime as an input or +be `static`. + +Additionally, note that returning references without input is banned if it +would result in returning references to invalid data. The following example shows +off some valid forms of functions with lifetimes: + +```rust,editable +// One input reference with lifetime `'a` which must live +// at least as long as the function. +fn print_one<'a>(x: &'a i32) { + println!("`print_one`: x is {}", x); +} + +// Mutable references are possible with lifetimes as well. +fn add_one<'a>(x: &'a mut i32) { + *x += 1; +} + +// Multiple elements with different lifetimes. In this case, it +// would be fine for both to have the same lifetime `'a`, but +// in more complex cases, different lifetimes may be required. +fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { + println!("`print_multi`: x is {}, y is {}", x, y); +} + +// Returning references that have been passed in is acceptable. +// However, the correct lifetime must be returned. +fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } + +//fn invalid_output<'a>() -> &'a i32 { &7 } +// The above is invalid: `'a` must live longer than the function. +// Here, `&7` would create an `i32`, followed by a reference. +// Then the data is dropped upon exiting the scope, leaving +// a reference to invalid data to be returned. + +fn main() { + let x = 7; + let y = 9; + + print_one(&x); + print_multi(&x, &y); + + let z = pass_x(&x, &y); + print_one(z); + + let mut t = 3; + add_one(&mut t); + print_one(&t); +} +``` + +### See also: + +[functions][fn] + +[elision]: /scope/lifetime/elision.html +[fn]: /fn.html diff --git a/src/scope/lifetime/lifetime_bounds.md b/src/scope/lifetime/lifetime_bounds.md index b63c350b05..17aff6c377 100644 --- a/src/scope/lifetime/lifetime_bounds.md +++ b/src/scope/lifetime/lifetime_bounds.md @@ -1 +1,53 @@ # Bounds + +Just like generic types can be bounded, lifetimes (themselves generic) +use bounds as well. The `:` character has a slightly different meaning here, +but `+` is the same. Note how the following read: + +1. `T: 'a`: *All* references in `T` must outlive lifetime `'a`. +2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references +in `T` must outlive `'a`. + +The example below shows the above syntax in action: + +```rust,editable +use std::fmt::Debug; // Trait to bound with. + +#[derive(Debug)] +struct Ref<'a, T: 'a>(&'a T); +// `Ref` contains a reference to a generic type `T` that has +// an unknown lifetime `'a`. `T` is bounded such that any +// *references* in `T` must outlive `'a`. Additionally, the lifetime +// of `Ref` may not exceed `'a`. + +// A generic function which prints using the `Debug` trait. +fn print(t: T) where + T: Debug { + println!("`print`: t is {:?}", t); +} + +// Here a reference to `T` is taken where `T` implements +// `Debug` and all *references* in `T` outlive `'a`. In +// addition, `'a` must outlive the function. +fn print_ref<'a, T>(t: &'a T) where + T: Debug + 'a { + println!("`print_ref`: t is {:?}", t); +} + +fn main() { + let x = 7; + let ref_x = Ref(&x); + + print_ref(&ref_x); + print(ref_x); +} +``` + +### See also: + +[generics][generics], [bounds in generics][bounds], and +[multiple bounds in generics][multibounds] + +[generics]: /generics.html +[bounds]: /generics/bounds.html +[multibounds]: /generics/multi_bounds.html \ No newline at end of file diff --git a/src/scope/lifetime/lifetime_coercion.md b/src/scope/lifetime/lifetime_coercion.md index fc095e3ce8..96090f4803 100644 --- a/src/scope/lifetime/lifetime_coercion.md +++ b/src/scope/lifetime/lifetime_coercion.md @@ -1 +1,31 @@ # Coercion + +A longer lifetime can be coerced into a shorter one +so that it works inside a scope it normally wouldn't work in. +This comes in the form of inferred coercion by the Rust compiler, +and also in the form of declaring a lifetime difference: + +```rust,editable +// Here, Rust infers a lifetime that is as short as possible. +// The two references are then coerced to that lifetime. +fn multiply<'a>(first: &'a i32, second: &'a i32) -> i32 { + first * second +} + +// `<'a: 'b, 'b>` reads as lifetime `'a` is at least as long as `'b`. +// Here, we take in an `&'a i32` and return a `&'b i32` as a result of coercion. +fn choose_first<'a: 'b, 'b>(first: &'a i32, _: &'b i32) -> &'b i32 { + first +} + +fn main() { + let first = 2; // Longer lifetime + + { + let second = 3; // Shorter lifetime + + println!("The product is {}", multiply(&first, &second)); + println!("{} is the first", choose_first(&first, &second)); + }; +} +``` \ No newline at end of file diff --git a/src/scope/lifetime/methods.md b/src/scope/lifetime/methods.md index 8f834183a1..8e1a508bbd 100644 --- a/src/scope/lifetime/methods.md +++ b/src/scope/lifetime/methods.md @@ -1 +1,28 @@ # Methods + +Methods are annotated similarly to functions: + +```rust,editable +struct Owner(i32); + +impl Owner { + // Annotate lifetimes as in a standalone function. + fn add_one<'a>(&'a mut self) { self.0 += 1; } + fn print<'a>(&'a self) { + println!("`print`: {}", self.0); + } +} + +fn main() { + let mut owner = Owner(18); + + owner.add_one(); + owner.print(); +} +``` + +### See also: + +[methods][methods] + +[methods]: /fn/methods.html \ No newline at end of file diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index c98f91218d..dbf0082ce1 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -1 +1,52 @@ # static + +A `'static` lifetime is the longest possible lifetime, and lasts for +the lifetime of the running program. A `'static` lifetime may also be +coerced to a shorter lifetime. There are two ways to make a variable +with `'static` lifetime, and both are stored in the read-only memory +of the binary: + +* Make a constant with the `static` declaration. +* Make a `string` literal which has type: `&'static str`. + +See the following example for a display of each method: + +```rust,editable +// Make a constant with `'static` lifetime. +static NUM: i32 = 18; + +// Returns a reference to `NUM` where its `'static` +// lifetime is coerced to that of the input argument. +fn coerce_static<'a>(_: &'a i32) -> &'a i32 { + &NUM +} + +fn main() { + { + // Make a `string` literal and print it: + let static_string = "I'm in read-only memory"; + println!("static_string: {}", static_string); + + // When `static_string` goes out of scope, the reference + // can no longer be used, but the data remains in the binary. + } + + { + // Make an integer to use for `coerce_static`: + let lifetime_num = 9; + + // Coerce `NUM` to lifetime of `lifetime_num`: + let coerced_static = coerce_static(&lifetime_num); + + println!("coerced_static: {}", coerced_static); + } + + println!("NUM: {} stays accessible!", NUM); +} +``` + +### See also: + +[`'static` constants][static_const] + +[static_const]: /custom_types/constants.html \ No newline at end of file diff --git a/src/scope/lifetime/struct.md b/src/scope/lifetime/struct.md index c88ba870a2..39dc824675 100644 --- a/src/scope/lifetime/struct.md +++ b/src/scope/lifetime/struct.md @@ -1 +1,46 @@ # Structs + +Annotation of lifetimes in structures are also similar to functions: + +```rust,editable +// A type `Borrowed` which houses a reference to an +// `i32`. The reference to `i32` must outlive `Borrowed`. +#[derive(Debug)] +struct Borrowed<'a>(&'a i32); + +// Similarly, both references here must outlive this structure. +#[derive(Debug)] +struct NamedBorrowed<'a> { + x: &'a i32, + y: &'a i32, +} + +// An enum which is either an `i32` or a reference to one. +#[derive(Debug)] +enum Either<'a> { + Num(i32), + Ref(&'a i32), +} + +fn main() { + let x = 18; + let y = 15; + + let single = Borrowed(&x); + let double = NamedBorrowed { x: &x, y: &y }; + let reference = Either::Ref(&x); + let number = Either::Num(y); + + println!("x is borrowed in {:?}", single); + println!("x and y are borrowed in {:?}", double); + println!("x is borrowed in {:?}", reference); + println!("y is *not* borrowed in {:?}", number); +} +``` + +### See also: + +[`structs`][structs] + + +[structs]: /custom_types/structs.html diff --git a/src/scope/move.md b/src/scope/move.md index 4953c4f0c0..dd4085ac1d 100644 --- a/src/scope/move.md +++ b/src/scope/move.md @@ -1 +1,60 @@ # Ownership and moves + +Because variables are in charge of freeing their own resources, +**resources can only have one owner**. This also prevents resources +from being freed more than once. Note that not all variables own +resources (e.g. [references]). + +When doing assignments (`let x = y`) or passing function arguments by value +(`foo(x)`), the *ownership* of the resources is transferred. In Rust-speak, +this is known as a *move*. + +After moving resources, the previous owner can no longer be used. This avoids +creating dangling pointers. + +```rust,editable +// This function takes ownership of the heap allocated memory +fn destroy_box(c: Box) { + println!("Destroying a box that contains {}", c); + + // `c` is destroyed and the memory freed +} + +fn main() { + // _Stack_ allocated integer + let x = 5u32; + + // *Copy* `x` into `y` - no resources are moved + let y = x; + + // Both values can be independently used + println!("x is {}, and y is {}", x, y); + + // `a` is a pointer to a _heap_ allocated integer + let a = Box::new(5i32); + + println!("a contains: {}", a); + + // *Move* `a` into `b` + let b = a; + // The pointer address of `a` is copied (not the data) into `b`. + // Both are now pointers to the same heap allocated data, but + // `b` now owns it. + + // Error! `a` can no longer access the data, because it no longer owns the + // heap memory + //println!("a contains: {}", a); + // TODO ^ Try uncommenting this line + + // This function takes ownership of the heap allocated memory from `b` + destroy_box(b); + + // Since the heap memory has been freed at this point, this action would + // result in dereferencing freed memory, but it's forbidden by the compiler + // Error! Same reason as the previous Error + //println!("b contains: {}", b); + // TODO ^ Try uncommenting this line +} +``` + +[references]: /flow_control/match/destructuring/destructure_pointers.html diff --git a/src/scope/move/mut.md b/src/scope/move/mut.md index b2197b1cec..3dddc4a17e 100644 --- a/src/scope/move/mut.md +++ b/src/scope/move/mut.md @@ -1 +1,24 @@ # Mutability + +Mutability of data can be changed when ownership is transferred. + +```rust,editable +fn main() { + let immutable_box = Box::new(5u32); + + println!("immutable_box contains {}", immutable_box); + + // Mutability error + //*immutable_box = 4; + + // *Move* the box, changing the ownership (and mutability) + let mut mutable_box = immutable_box; + + println!("mutable_box contains {}", mutable_box); + + // Modify the contents of the box + *mutable_box = 4; + + println!("mutable_box now contains {}", mutable_box); +} +``` \ No newline at end of file diff --git a/src/scope/raii.md b/src/scope/raii.md index a9ce14a6b1..481e447407 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -1 +1,70 @@ # RAII + +Variables in Rust do more than just hold data in the stack: they also *own* +resources, e.g. `Box` owns memory in the heap. Rust enforces [RAII][raii] +(Resource Acquisition Is Initialization), so whenever an object goes out of +scope, its destructor is called and its owned resources are freed. + +This behavior shields against *resource leak* bugs, so you'll never have to +manually free memory or worry about memory leaks again! Here's a quick showcase: + +```rust,editable +// raii.rs +fn create_box() { + // Allocate an integer on the heap + let _box1 = Box::new(3i32); + + // `_box1` is destroyed here, and memory gets freed +} + +fn main() { + // Allocate an integer on the heap + let _box2 = Box::new(5i32); + + // A nested scope: + { + // Allocate an integer on the heap + let _box3 = Box::new(4i32); + + // `_box3` is destroyed here, and memory gets freed + } + + // Creating lots of boxes just for fun + // There's no need to manually free memory! + for _ in 0u32..1_000 { + create_box(); + } + + // `_box2` is destroyed here, and memory gets freed +} +``` + +Of course, we can double check for memory errors using [`valgrind`][valgrind]: + +```bash +$ rustc raii.rs && valgrind ./raii +==26873== Memcheck, a memory error detector +==26873== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==26873== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info +==26873== Command: ./raii +==26873== +==26873== +==26873== HEAP SUMMARY: +==26873== in use at exit: 0 bytes in 0 blocks +==26873== total heap usage: 1,013 allocs, 1,013 frees, 8,696 bytes allocated +==26873== +==26873== All heap blocks were freed -- no leaks are possible +==26873== +==26873== For counts of detected and suppressed errors, rerun with: -v +==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) +``` + +No leaks here! + +### See also: + +[Box][box] + +[raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization +[box]: /std/box.html +[valgrind]: http://valgrind.org/info/ \ No newline at end of file From ec97e9d5ab77923312172a57eb81b495c2ed5d98 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 12 Sep 2017 19:06:03 -0400 Subject: [PATCH 0650/1122] Chapter: generics --- examples/generics/assoc_items/input.md | 13 --- .../generics/assoc_items/the_problem/input.md | 20 ----- .../assoc_items/the_problem/problem.rs | 44 ---------- examples/generics/assoc_items/types/input.md | 32 ------- examples/generics/assoc_items/types/types.rs | 50 ----------- examples/generics/bounds/bounds.rs | 38 -------- examples/generics/bounds/input.md | 40 --------- .../generics/bounds/testcase_empty/empty.rs | 27 ------ .../generics/bounds/testcase_empty/input.md | 13 --- examples/generics/gen_fn/fn.rs | 38 -------- examples/generics/gen_fn/input.md | 19 ---- examples/generics/gen_trait/input.md | 12 --- examples/generics/gen_trait/trait.rs | 30 ------- examples/generics/generics.rs | 27 ------ examples/generics/impl/impl.rs | 25 ------ examples/generics/impl/input.md | 25 ------ examples/generics/input.md | 34 -------- examples/generics/multi_bounds/input.md | 11 --- examples/generics/multi_bounds/multi.rs | 23 ----- examples/generics/phantom/input.md | 21 ----- examples/generics/phantom/phantom.rs | 39 --------- .../generics/phantom/testcase_units/input.md | 37 -------- .../generics/phantom/testcase_units/units.rs | 49 ----------- examples/generics/where/input.md | 30 ------- examples/generics/where/where.rs | 22 ----- src/generics.md | 63 ++++++++++++++ src/generics/assoc_items.md | 14 +++ src/generics/assoc_items/the_problem.md | 66 ++++++++++++++ src/generics/assoc_items/types.md | 84 ++++++++++++++++++ src/generics/bounds.md | 80 +++++++++++++++++ src/generics/bounds/testcase_empty.md | 42 +++++++++ src/generics/gen_fn.md | 58 +++++++++++++ src/generics/gen_trait.md | 44 ++++++++++ src/generics/impl.md | 51 +++++++++++ src/generics/multi_bounds.md | 36 ++++++++ src/generics/phantom.md | 62 +++++++++++++ src/generics/phantom/testcase_units.md | 87 +++++++++++++++++++ src/generics/where.md | 54 ++++++++++++ 38 files changed, 741 insertions(+), 719 deletions(-) delete mode 100644 examples/generics/assoc_items/input.md delete mode 100644 examples/generics/assoc_items/the_problem/input.md delete mode 100644 examples/generics/assoc_items/the_problem/problem.rs delete mode 100644 examples/generics/assoc_items/types/input.md delete mode 100644 examples/generics/assoc_items/types/types.rs delete mode 100644 examples/generics/bounds/bounds.rs delete mode 100644 examples/generics/bounds/input.md delete mode 100644 examples/generics/bounds/testcase_empty/empty.rs delete mode 100644 examples/generics/bounds/testcase_empty/input.md delete mode 100644 examples/generics/gen_fn/fn.rs delete mode 100644 examples/generics/gen_fn/input.md delete mode 100644 examples/generics/gen_trait/input.md delete mode 100644 examples/generics/gen_trait/trait.rs delete mode 100644 examples/generics/generics.rs delete mode 100644 examples/generics/impl/impl.rs delete mode 100644 examples/generics/impl/input.md delete mode 100644 examples/generics/input.md delete mode 100644 examples/generics/multi_bounds/input.md delete mode 100644 examples/generics/multi_bounds/multi.rs delete mode 100644 examples/generics/phantom/input.md delete mode 100644 examples/generics/phantom/phantom.rs delete mode 100644 examples/generics/phantom/testcase_units/input.md delete mode 100644 examples/generics/phantom/testcase_units/units.rs delete mode 100644 examples/generics/where/input.md delete mode 100644 examples/generics/where/where.rs diff --git a/examples/generics/assoc_items/input.md b/examples/generics/assoc_items/input.md deleted file mode 100644 index 8d199e802f..0000000000 --- a/examples/generics/assoc_items/input.md +++ /dev/null @@ -1,13 +0,0 @@ -"Associated Items" refers to a set of rules pertaining to [`item`][items]s -of various types. It is an extension to `trait` generics, and allows -`trait`s to internally define new items. - -One such item is called an *associated type*, providing simpler usage -patterns when the `trait` is generic over its container type. - -### See also: - -[RFC][RFC] - -[items]: https://doc.rust-lang.org/reference/items.html -[RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md diff --git a/examples/generics/assoc_items/the_problem/input.md b/examples/generics/assoc_items/the_problem/input.md deleted file mode 100644 index a65ec4d2bb..0000000000 --- a/examples/generics/assoc_items/the_problem/input.md +++ /dev/null @@ -1,20 +0,0 @@ -A `trait` that is generic over its container type has type specification -requirements - users of the `trait` *must* specify all of its generic types. - -In the example below, the `Contains` `trait` allows the use of the generic -types `A` and `B`. The trait is then implemented for the `Container` type, -specifying `i32` for `A` and `B` so that it can be used with `fn difference()`. - -Because `Contains` is generic, we are forced to explicitly state *all* of the -generic types for `fn difference()`. In practice, we want a way to express that -`A` and `B` are determined by the *input* `C`. As you will see in the next -section, associated types provide exactly that capability. - -{problem.play} - -### See also: - -[`struct`s][structs], and [`trait`s][traits] - -[structs]: /custom_types/structs.html -[traits]: /trait.html diff --git a/examples/generics/assoc_items/the_problem/problem.rs b/examples/generics/assoc_items/the_problem/problem.rs deleted file mode 100644 index 6c7d662b77..0000000000 --- a/examples/generics/assoc_items/the_problem/problem.rs +++ /dev/null @@ -1,44 +0,0 @@ -struct Container(i32, i32); - -// A trait which checks if 2 items are stored inside of container. -// Also retrieves first or last value. -trait Contains { - fn contains(&self, &A, &B) -> bool; // Explicitly requires `A` and `B`. - fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`. - fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`. -} - -impl Contains for Container { - // True if the numbers stored are equal. - fn contains(&self, number_1: &i32, number_2: &i32) -> bool { - (&self.0 == number_1) && (&self.1 == number_2) - } - - // Grab the first number. - fn first(&self) -> i32 { self.0 } - - // Grab the last number. - fn last(&self) -> i32 { self.1 } -} - -// `C` contains `A` and `B`. In light of that, having to express `A` and -// `B` again is a nuisance. -fn difference(container: &C) -> i32 where - C: Contains { - container.last() - container.first() -} - -fn main() { - let number_1 = 3; - let number_2 = 10; - - let container = Container(number_1, number_2); - - println!("Does container contain {} and {}: {}", - &number_1, &number_2, - container.contains(&number_1, &number_2)); - println!("First number: {}", container.first()); - println!("Last number: {}", container.last()); - - println!("The difference is: {}", difference(&container)); -} diff --git a/examples/generics/assoc_items/types/input.md b/examples/generics/assoc_items/types/input.md deleted file mode 100644 index 754cb91f16..0000000000 --- a/examples/generics/assoc_items/types/input.md +++ /dev/null @@ -1,32 +0,0 @@ -The use of "Associated types" improves the overall readability of code -by moving inner types locally into a trait as *output* types. Syntax -for the `trait` definition is as follows: - -```rust -// `A` and `B` are defined in the trait via the `type` keyword. -// (Note: `type` in this context is different from `type` when used for -// aliases). -trait Contains { - type A; - type B; - - // Updated syntax to refer to these new types generically. - fn contains(&self, &Self::A, &Self::B) -> bool; -} -``` - -Note that functions that use the `trait` `Contains` are no longer required -to express `A` or `B` at all: - -```rust -// Without using associated types -fn difference(container: &C) -> i32 where - C: Contains { ... } - -// Using associated types -fn difference(container: &C) -> i32 { ... } -``` - -Let's rewrite the example from the previous section using associated types: - -{types.play} diff --git a/examples/generics/assoc_items/types/types.rs b/examples/generics/assoc_items/types/types.rs deleted file mode 100644 index e3f9d9638e..0000000000 --- a/examples/generics/assoc_items/types/types.rs +++ /dev/null @@ -1,50 +0,0 @@ -struct Container(i32, i32); - -// A trait which checks if 2 items are stored inside of container. -// Also retrieves first or last value. -trait Contains { - // Define generic types here which methods will be able to utilize. - type A; - type B; - - fn contains(&self, &Self::A, &Self::B) -> bool; - fn first(&self) -> i32; - fn last(&self) -> i32; -} - -impl Contains for Container { - // Specify what types `A` and `B` are. If the `input` type - // is `Container(i32, i32)`, the `output` types are determined - // as `i32` and `i32`. - type A = i32; - type B = i32; - - // `&Self::A` and `&Self::B` are also valid here. - fn contains(&self, number_1: &i32, number_2: &i32) -> bool { - (&self.0 == number_1) && (&self.1 == number_2) - } - // Grab the first number. - fn first(&self) -> i32 { self.0 } - - // Grab the last number. - fn last(&self) -> i32 { self.1 } -} - -fn difference(container: &C) -> i32 { - container.last() - container.first() -} - -fn main() { - let number_1 = 3; - let number_2 = 10; - - let container = Container(number_1, number_2); - - println!("Does container contain {} and {}: {}", - &number_1, &number_2, - container.contains(&number_1, &number_2)); - println!("First number: {}", container.first()); - println!("Last number: {}", container.last()); - - println!("The difference is: {}", difference(&container)); -} diff --git a/examples/generics/bounds/bounds.rs b/examples/generics/bounds/bounds.rs deleted file mode 100644 index f652952aaf..0000000000 --- a/examples/generics/bounds/bounds.rs +++ /dev/null @@ -1,38 +0,0 @@ -// A trait which implements the print marker: `{:?}`. -use std::fmt::Debug; - -trait HasArea { - fn area(&self) -> f64; -} - -impl HasArea for Rectangle { - fn area(&self) -> f64 { self.length * self.height } -} - -#[derive(Debug)] -struct Rectangle { length: f64, height: f64 } -#[allow(dead_code)] -struct Triangle { length: f64, height: f64 } - -// The generic `T` must implement `Debug`. Regardless -// of the type, this will work properly. -fn print_debug(t: &T) { - println!("{:?}", t); -} - -// `T` must implement `HasArea`. Any function which meets -// the bound can access `HasArea`'s function `area`. -fn area(t: &T) -> f64 { t.area() } - -fn main() { - let rectangle = Rectangle { length: 3.0, height: 4.0 }; - let _triangle = Triangle { length: 3.0, height: 4.0 }; - - print_debug(&rectangle); - println!("Area: {}", area(&rectangle)); - - //print_debug(&_triangle); - //println!("Area: {}", area(&_triangle)); - // ^ TODO: Try uncommenting these. - // | Error: Does not implement either `Debug` or `HasArea`. -} diff --git a/examples/generics/bounds/input.md b/examples/generics/bounds/input.md deleted file mode 100644 index 17b40202c5..0000000000 --- a/examples/generics/bounds/input.md +++ /dev/null @@ -1,40 +0,0 @@ -When working with generics, the type parameters often must use traits as *bounds* to -stipulate what functionality a type implements. For example, the following -example uses the trait `Display` to print and so it requires `T` to be bound -by `Display`; that is, `T` *must* implement `Display`. - -```rust -// Define a function `printer` that takes a generic type `T` which -// must implement trait `Display`. -fn printer(t: T) { - println!("{}", t); -} -``` - -Bounding restricts the generic to types that conform to the bounds. That is: - -```rust -struct S(T); - -// Error! `Vec` does not implement `Display`. This -// specialization will fail. -let s = S(vec![1]); -``` - -Another effect of bounding is that generic instances are allowed to access the -[methods] of traits specified in the bounds. For example: - -{bounds.play} - -As an additional note, [`where`][where] clauses can also be used to apply bounds in -some cases to be more expressive. - -### See also: - -[`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] - -[fmt]: /hello/print.html -[methods]: /fn/methods.html -[structs]: /custom_types/structs.html -[traits]: /trait.html -[where]: /generics/where.html \ No newline at end of file diff --git a/examples/generics/bounds/testcase_empty/empty.rs b/examples/generics/bounds/testcase_empty/empty.rs deleted file mode 100644 index c19dbdbd36..0000000000 --- a/examples/generics/bounds/testcase_empty/empty.rs +++ /dev/null @@ -1,27 +0,0 @@ -struct Cardinal; -struct BlueJay; -struct Turkey; - -trait Red {} -trait Blue {} - -impl Red for Cardinal {} -impl Blue for BlueJay {} - -// These functions are only valid for types which implement these -// traits. The fact that the traits are empty is irrelevant. -fn red(_: &T) -> &'static str { "red" } -fn blue(_: &T) -> &'static str { "blue" } - -fn main() { - let cardinal = Cardinal; - let blue_jay = BlueJay; - let _turkey = Turkey; - - // `red()` won't work on a blue jay nor vice versa - // because of the bounds. - println!("A cardinal is {}", red(&cardinal)); - println!("A blue jay is {}", blue(&blue_jay)); - //println!("A turkey is {}", red(&_turkey)); - // ^ TODO: Try uncommenting this line. -} diff --git a/examples/generics/bounds/testcase_empty/input.md b/examples/generics/bounds/testcase_empty/input.md deleted file mode 100644 index 4d74f72c0f..0000000000 --- a/examples/generics/bounds/testcase_empty/input.md +++ /dev/null @@ -1,13 +0,0 @@ -A consequence of how bounds work is that even if a `trait` doesn't -include any functionality, you can still use it as a bound. `Eq` and -`Ord` are examples of such `trait`s from the `std` library. - -{empty.play} - -### See also: - -[`std::cmp::Eq`][eq], [`std::cmp::Ord`s][ord], and [`trait`s][traits] - -[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html -[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html -[traits]: /trait.html diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs deleted file mode 100644 index 04bcb31bce..0000000000 --- a/examples/generics/gen_fn/fn.rs +++ /dev/null @@ -1,38 +0,0 @@ -struct A; // Concrete type `A`. -struct S(A); // Concrete type `S`. -struct SGen(T); // Generic type `SGen`. - -// The following functions all take ownership of the variable passed into -// them and immediately go out of scope, freeing the variable. - -// Define a function `reg_fn` that takes an argument `_s` of type `S`. -// This has no `` so this is not a generic function. -fn reg_fn(_s: S) {} - -// Define a function `gen_spec_t` that takes an argument `_s` of type `SGen`. -// It has been explicitly given the type parameter `A`, but because `A` has not -// been specified as a generic type parameter for `gen_spec_t`, it is not generic. -fn gen_spec_t(_s: SGen) {} - -// Define a function `gen_spec_i32` that takes an argument `_s` of type `SGen`. -// It has been explicitly given the type parameter `i32`, which is a specific type. -// Because `i32` is not a generic type, this function is also not generic. -fn gen_spec_i32(_s: SGen) {} - -// Define a function `generic` that takes an argument `_s` of type `SGen`. -// Because `SGen` is preceded by ``, this function is generic over `T`. -fn generic(_s: SGen) {} - -fn main() { - // Using the non-generic functions - reg_fn(S(A)); // Concrete type. - gen_spec_t(SGen(A)); // Implicitly specified type parameter `A`. - gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`. - - // Explicitly specified type parameter `char` to `generic()`. - generic::(SGen('a')); - - // Implicitly specified type parameter `char` to `generic()`. - generic(SGen('c')); -} - diff --git a/examples/generics/gen_fn/input.md b/examples/generics/gen_fn/input.md deleted file mode 100644 index bb4a478d49..0000000000 --- a/examples/generics/gen_fn/input.md +++ /dev/null @@ -1,19 +0,0 @@ -The same set of rules can be applied to functions: a type `T` becomes -generic when preceded by ``. - -Using generic functions sometimes requires explicitly specifying type -parameters. This may be the case if the function is called where the return type -is generic, or if the compiler doesn't have enough information to infer -the necessary type parameters. - -A function call with explicitly specified type parameters looks like: -`fun::()`. - -{fn.play} - -### See also: - -[functions][fn] and [`struct`s][structs] - -[fn]: /fn.html -[structs]: /custom_types/structs.html diff --git a/examples/generics/gen_trait/input.md b/examples/generics/gen_trait/input.md deleted file mode 100644 index 0b6b919c40..0000000000 --- a/examples/generics/gen_trait/input.md +++ /dev/null @@ -1,12 +0,0 @@ -Of course `trait`s can also be generic. Here we define one which reimplements -the `Drop` `trait` as a generic method to `drop` itself and an input. - -{trait.play} - -### See also: - -[`Drop`][Drop], [`struct`][structs], and [`trait`][traits] - -[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html -[structs]: /custom_types/structs.html -[traits]: /trait.html diff --git a/examples/generics/gen_trait/trait.rs b/examples/generics/gen_trait/trait.rs deleted file mode 100644 index abaa12bc5c..0000000000 --- a/examples/generics/gen_trait/trait.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Non-copyable types. -struct Empty; -struct Null; - -// A trait generic over `T`. -trait DoubleDrop { - // Define a method on the caller type which takes an - // additional single parameter `T` and does nothing with it. - fn double_drop(self, _: T); -} - -// Implement `DoubleDrop` for any generic parameter `T` and -// caller `U`. -impl DoubleDrop for U { - // This method takes ownership of both passed arguments, - // deallocating both. - fn double_drop(self, _: T) {} -} - -fn main() { - let empty = Empty; - let null = Null; - - // Deallocate `empty` and `null`. - empty.double_drop(null); - - //empty; - //null; - // ^ TODO: Try uncommenting these lines. -} diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs deleted file mode 100644 index 6386f82246..0000000000 --- a/examples/generics/generics.rs +++ /dev/null @@ -1,27 +0,0 @@ -// A concrete type `A`. -struct A; - -// In defining the type `Single`, the first use of `A` is not preceded by ``. -// Therefore, `Single` is a concrete type, and `A` is defined as above. -struct Single(A); -// ^ Here is `Single`s first use of the type `A`. - -// Here, `` precedes the first use of `T`, so `SingleGen` is a generic type. -// Because the type parameter `T` is generic, it could be anything, including -// the concrete type `A` defined at the top. -struct SingleGen(T); - -fn main() { - // `Single` is concrete and explicitly takes `A`. - let _s = Single(A); - - // Create a variable `_char` of type `SingleGen` - // and give it the value `SingleGen('a')`. - // Here, `SingleGen` has a type parameter explicitly specified. - let _char: SingleGen = SingleGen('a'); - - // `SingleGen` can also have a type parameter implicitly specified: - let _t = SingleGen(A); // Uses `A` defined at the top. - let _i32 = SingleGen(6); // Uses `i32`. - let _char = SingleGen('a'); // Uses `char`. -} diff --git a/examples/generics/impl/impl.rs b/examples/generics/impl/impl.rs deleted file mode 100644 index 85f5d9134e..0000000000 --- a/examples/generics/impl/impl.rs +++ /dev/null @@ -1,25 +0,0 @@ -struct Val { - val: f64 -} - -struct GenVal{ - gen_val: T -} - -// impl of Val -impl Val { - fn value(&self) -> &f64 { &self.val } -} - -// impl of GenVal for a generic type `T` -impl GenVal { - fn value(&self) -> &T { &self.gen_val } -} - -fn main() { - let x = Val { val: 3.0 }; - let y = GenVal { gen_val: 3i32 }; - - println!("{}, {}", x.value(), y.value()); -} - diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md deleted file mode 100644 index a8947f4281..0000000000 --- a/examples/generics/impl/input.md +++ /dev/null @@ -1,25 +0,0 @@ -Similar to functions, implementations require care to remain generic. - -```rust -struct S; // Concrete type `S` -struct GenericVal(T,); // Generic type `GenericVal` - -// impl of GenericVal where we explicitly specify type parameters: -impl GenericVal {} // Specify `f32` -impl GenericVal {} // Specify `S` as defined above - -// `` Must precede the type to remain generic -impl GenericVal {} -``` - -{impl.play} - -### See also: - -[functions returning references][fn], [`impl`][methods], and [`struct`][structs] - - -[fn]: /scope/lifetime/fn.html -[methods]: /fn/methods.html -[specialization_plans]: https://blog.rust-lang.org/2015/05/11/traits.html#the-future -[structs]: /custom_types/structs.html diff --git a/examples/generics/input.md b/examples/generics/input.md deleted file mode 100644 index f6f10cee6b..0000000000 --- a/examples/generics/input.md +++ /dev/null @@ -1,34 +0,0 @@ -*Generics* is the topic of generalizing types and functionalities to broader -cases. This is extremely useful for reducing code duplication in many ways, -but can call for rather involving syntax. Namely, being generic requires -taking great care to specify over which types a generic type -is actually considered valid. The simplest and most common use of generics -is for type parameters. - -A type parameter is specified as generic by the use of angle brackets and upper -[camel case][camelcase]: ``. "Generic type parameters" are -typically represented as ``. In Rust, "generic" also describes anything that -accepts one or more generic type parameters ``. Any type specified as a -generic type parameter is generic, and everything else is concrete (non-generic). - -For example, defining a *generic function* named `foo` that takes an argument -`T` of any type: - -```rust -fn foo(T) { ... } -``` - -Because `T` has been specified as a generic type parameter using ``, it -is considered generic when used here as `(T)`. This is the case even if `T` -has previously been defined as a `struct`. - -This example shows some of the syntax in action: - -{generics.play} - -### See also: - -[`struct`s][structs] - -[structs]: /custom_types/structs.html -[camelcase]: https://en.wikipedia.org/wiki/CamelCase \ No newline at end of file diff --git a/examples/generics/multi_bounds/input.md b/examples/generics/multi_bounds/input.md deleted file mode 100644 index a628ef1943..0000000000 --- a/examples/generics/multi_bounds/input.md +++ /dev/null @@ -1,11 +0,0 @@ -Multiple bounds can be applied with a `+`. Like normal, different types are -separated with `,`. - -{multi.play} - -### See also: - -[`std::fmt`][fmt] and [`trait`s][traits] - -[fmt]: /hello/print.html -[traits]: /trait.html diff --git a/examples/generics/multi_bounds/multi.rs b/examples/generics/multi_bounds/multi.rs deleted file mode 100644 index 0db273d34f..0000000000 --- a/examples/generics/multi_bounds/multi.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::fmt::{Debug, Display}; - -fn compare_prints(t: &T) { - println!("Debug: `{:?}`", t); - println!("Display: `{}`", t); -} - -fn compare_types(t: &T, u: &U) { - println!("t: `{:?}", t); - println!("u: `{:?}", u); -} - -fn main() { - let string = "words"; - let array = [1, 2, 3]; - let vec = vec![1, 2, 3]; - - compare_prints(&string); - //compare_prints(&array); - // TODO ^ Try uncommenting this. - - compare_types(&array, &vec); -} diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md deleted file mode 100644 index ad65e2eee3..0000000000 --- a/examples/generics/phantom/input.md +++ /dev/null @@ -1,21 +0,0 @@ -A phantom type parameter is one that doesn't show up at runtime, -but is checked statically (and only) at compile time. - -Data types can use extra generic type parameters to act as markers -or to perform type checking at compile time. These extra parameters -hold no storage values, and have no runtime behavior. - -In the following example, we combine [std::marker::PhantomData] -with the phantom type parameter concept to create tuples containing -different data types. - -{phantom.play} - -### See also: - -[Derive], [struct], and [TupleStructs] - -[Derive]: /trait/derive.html -[struct]: /custom_types/structs.html -[TupleStructs]: /custom_types/structs.html -[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs deleted file mode 100644 index 16217c0135..0000000000 --- a/examples/generics/phantom/phantom.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::marker::PhantomData; - -// A phantom tuple struct which is generic over `A` with hidden parameter `B`. -#[derive(PartialEq)] // Allow equality test for this type. -struct PhantomTuple(A,PhantomData); - -// A phantom type struct which is generic over `A` with hidden parameter `B`. -#[derive(PartialEq)] // Allow equality test for this type. -struct PhantomStruct { first: A, phantom: PhantomData } - -// Note: Storage is allocated for generic type `A`, but not for `B`. -// Therefore, `B` cannot be used in computations. - -fn main() { - // Here, `f32` and `f64` are the hidden parameters. - // PhantomTuple type specified as ``. - let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); - // PhantomTuple type specified as ``. - let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); - - // Type specified as ``. - let _struct1: PhantomStruct = PhantomStruct { - first: 'Q', - phantom: PhantomData, - }; - // Type specified as ``. - let _struct2: PhantomStruct = PhantomStruct { - first: 'Q', - phantom: PhantomData, - }; - - // Compile-time Error! Type mismatch so these cannot be compared: - //println!("_tuple1 == _tuple2 yields: {}", - // _tuple1 == _tuple2); - - // Compile-time Error! Type mismatch so these cannot be compared: - //println!("_struct1 == _struct2 yields: {}", - // _struct1 == _struct2); -} \ No newline at end of file diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md deleted file mode 100644 index f354c148b4..0000000000 --- a/examples/generics/phantom/testcase_units/input.md +++ /dev/null @@ -1,37 +0,0 @@ -A useful method of unit conversions can be examined by implementing `Add` -with a phantom type parameter. The `Add` `trait` is examined below: - -```rust -// This construction would impose: `Self + RHS = Output` -// where RHS defaults to Self if not specified in the implementation. -pub trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -// `Output` must be `T` so that `T + T = T`. -impl Add for T { - type Output = T; - ... -} -``` - -The whole implementation: - -{units.play} - -### See also: - -[Borrowing (`&`)], [Bounds (`X: Y`)], [enum], [impl & self], -[Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. - -[Borrowing (`&`)]: /scope/borrow.html -[Bounds (`X: Y`)]: /generics/bounds.html -[enum]: /custom_types/enum.html -[impl & self]: /fn/methods.html -[Overloading]: /trait/ops.html -[ref]: /scope/borrow/ref.html -[Traits (`X for Y`)]: /trait.html -[TupleStructs]: /custom_types/structs.html -[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs deleted file mode 100644 index 18be5e9aba..0000000000 --- a/examples/generics/phantom/testcase_units/units.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::ops::Add; -use std::marker::PhantomData; - -/// Create void enumerations to define unit types. -#[derive(Debug, Clone, Copy)] -enum Inch {} -#[derive(Debug, Clone, Copy)] -enum Mm {} - -/// `Length` is a type with phantom type parameter `Unit`, -/// and is not generic over the length type (that is `f64`). -/// -/// `f64` already implements the `Clone` and `Copy` traits. -#[derive(Debug, Clone, Copy)] -struct Length(f64, PhantomData); - -/// The `Add` trait defines the behavior of the `+` operator. -impl Add for Length { - type Output = Length; - - // add() returns a new `Length` struct containing the sum. - fn add(self, rhs: Length) -> Length { - // `+` calls the `Add` implementation for `f64`. - Length(self.0 + rhs.0, PhantomData) - } -} - -fn main() { - // Specifies `one_foot` to have phantom type parameter `Inch`. - let one_foot: Length = Length(12.0, PhantomData); - // `one_meter` has phantom type parameter `Mm`. - let one_meter: Length = Length(1000.0, PhantomData); - - // `+` calls the `add()` method we implemented for `Length`. - // - // Since `Length` implements `Copy`, `add()` does not consume - // `one_foot` and `one_meter` but copies them into `self` and `rhs`. - let two_feet = one_foot + one_foot; - let two_meters = one_meter + one_meter; - - // Addition works. - println!("one foot + one_foot = {:?} in", two_feet.0); - println!("one meter + one_meter = {:?} mm", two_meters.0); - - // Nonsensical operations fail as they should: - // Compile-time Error: type mismatch. - //let one_feter = one_foot + one_meter; -} - diff --git a/examples/generics/where/input.md b/examples/generics/where/input.md deleted file mode 100644 index f71edb3902..0000000000 --- a/examples/generics/where/input.md +++ /dev/null @@ -1,30 +0,0 @@ -A bound can also be expressed using a `where` clause immediately -before the opening `{`, rather than at the type's first mention. -Additionally, `where` clauses can apply bounds to arbitrary types, -rather than just to type parameters. - -Some cases that a `where` clause is useful: - -* When specifying generic types and bounds separately is clearer: - -```rust -impl MyTrait for YourType {} - -// Expressing bounds with a `where` clause -impl MyTrait for YourType where - A: TraitB + TraitC, - D: TraitE + TraitF {} -``` - -* When using a `where` clause is more expressive than using normal syntax. -The `impl` in this example cannot be directly expressed without a `where` clause: - -{where.play} - -### See also: - -[RFC][where], [`struct`][struct], and [`trait`][trait] - -[struct]: /custom_types/structs.html -[trait]: /trait.html -[where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md diff --git a/examples/generics/where/where.rs b/examples/generics/where/where.rs deleted file mode 100644 index 310547feea..0000000000 --- a/examples/generics/where/where.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::fmt::Debug; - -trait PrintInOption { - fn print_in_option(self); -} - -// Because we would otherwise have to express this as `T: Debug` or -// use another method of indirect approach, this requires a `where` clause: -impl PrintInOption for T where - Option: Debug { - // We want `Option: Debug` as our bound because that is what's - // being printed. Doing otherwise would be using the wrong bound. - fn print_in_option(self) { - println!("{:?}", Some(self)); - } -} - -fn main() { - let vec = vec![1, 2, 3]; - - vec.print_in_option(); -} diff --git a/src/generics.md b/src/generics.md index 292d26b987..fbe75d42b1 100644 --- a/src/generics.md +++ b/src/generics.md @@ -1 +1,64 @@ # Generics + +*Generics* is the topic of generalizing types and functionalities to broader +cases. This is extremely useful for reducing code duplication in many ways, +but can call for rather involving syntax. Namely, being generic requires +taking great care to specify over which types a generic type +is actually considered valid. The simplest and most common use of generics +is for type parameters. + +A type parameter is specified as generic by the use of angle brackets and upper +[camel case][camelcase]: ``. "Generic type parameters" are +typically represented as ``. In Rust, "generic" also describes anything that +accepts one or more generic type parameters ``. Any type specified as a +generic type parameter is generic, and everything else is concrete (non-generic). + +For example, defining a *generic function* named `foo` that takes an argument +`T` of any type: + +```rust +fn foo(T) { ... } +``` + +Because `T` has been specified as a generic type parameter using ``, it +is considered generic when used here as `(T)`. This is the case even if `T` +has previously been defined as a `struct`. + +This example shows some of the syntax in action: + +```rust,editable +// A concrete type `A`. +struct A; + +// In defining the type `Single`, the first use of `A` is not preceded by ``. +// Therefore, `Single` is a concrete type, and `A` is defined as above. +struct Single(A); +// ^ Here is `Single`s first use of the type `A`. + +// Here, `` precedes the first use of `T`, so `SingleGen` is a generic type. +// Because the type parameter `T` is generic, it could be anything, including +// the concrete type `A` defined at the top. +struct SingleGen(T); + +fn main() { + // `Single` is concrete and explicitly takes `A`. + let _s = Single(A); + + // Create a variable `_char` of type `SingleGen` + // and give it the value `SingleGen('a')`. + // Here, `SingleGen` has a type parameter explicitly specified. + let _char: SingleGen = SingleGen('a'); + + // `SingleGen` can also have a type parameter implicitly specified: + let _t = SingleGen(A); // Uses `A` defined at the top. + let _i32 = SingleGen(6); // Uses `i32`. + let _char = SingleGen('a'); // Uses `char`. +} +``` + +### See also: + +[`struct`s][structs] + +[structs]: /custom_types/structs.html +[camelcase]: https://en.wikipedia.org/wiki/CamelCase \ No newline at end of file diff --git a/src/generics/assoc_items.md b/src/generics/assoc_items.md index d1e932f016..7a3871bb76 100644 --- a/src/generics/assoc_items.md +++ b/src/generics/assoc_items.md @@ -1 +1,15 @@ # Associated items + +"Associated Items" refers to a set of rules pertaining to [`item`][items]s +of various types. It is an extension to `trait` generics, and allows +`trait`s to internally define new items. + +One such item is called an *associated type*, providing simpler usage +patterns when the `trait` is generic over its container type. + +### See also: + +[RFC][RFC] + +[items]: https://doc.rust-lang.org/reference/items.html +[RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md diff --git a/src/generics/assoc_items/the_problem.md b/src/generics/assoc_items/the_problem.md index 0e040b4d71..45cc3f62c4 100644 --- a/src/generics/assoc_items/the_problem.md +++ b/src/generics/assoc_items/the_problem.md @@ -1 +1,67 @@ # The Problem + +A `trait` that is generic over its container type has type specification +requirements - users of the `trait` *must* specify all of its generic types. + +In the example below, the `Contains` `trait` allows the use of the generic +types `A` and `B`. The trait is then implemented for the `Container` type, +specifying `i32` for `A` and `B` so that it can be used with `fn difference()`. + +Because `Contains` is generic, we are forced to explicitly state *all* of the +generic types for `fn difference()`. In practice, we want a way to express that +`A` and `B` are determined by the *input* `C`. As you will see in the next +section, associated types provide exactly that capability. + +```rust,editable +struct Container(i32, i32); + +// A trait which checks if 2 items are stored inside of container. +// Also retrieves first or last value. +trait Contains { + fn contains(&self, &A, &B) -> bool; // Explicitly requires `A` and `B`. + fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`. + fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`. +} + +impl Contains for Container { + // True if the numbers stored are equal. + fn contains(&self, number_1: &i32, number_2: &i32) -> bool { + (&self.0 == number_1) && (&self.1 == number_2) + } + + // Grab the first number. + fn first(&self) -> i32 { self.0 } + + // Grab the last number. + fn last(&self) -> i32 { self.1 } +} + +// `C` contains `A` and `B`. In light of that, having to express `A` and +// `B` again is a nuisance. +fn difference(container: &C) -> i32 where + C: Contains { + container.last() - container.first() +} + +fn main() { + let number_1 = 3; + let number_2 = 10; + + let container = Container(number_1, number_2); + + println!("Does container contain {} and {}: {}", + &number_1, &number_2, + container.contains(&number_1, &number_2)); + println!("First number: {}", container.first()); + println!("Last number: {}", container.last()); + + println!("The difference is: {}", difference(&container)); +} +``` + +### See also: + +[`struct`s][structs], and [`trait`s][traits] + +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/src/generics/assoc_items/types.md b/src/generics/assoc_items/types.md index a06af85e08..419aa4c596 100644 --- a/src/generics/assoc_items/types.md +++ b/src/generics/assoc_items/types.md @@ -1 +1,85 @@ # Associated types + +The use of "Associated types" improves the overall readability of code +by moving inner types locally into a trait as *output* types. Syntax +for the `trait` definition is as follows: + +```rust +// `A` and `B` are defined in the trait via the `type` keyword. +// (Note: `type` in this context is different from `type` when used for +// aliases). +trait Contains { + type A; + type B; + + // Updated syntax to refer to these new types generically. + fn contains(&self, &Self::A, &Self::B) -> bool; +} +``` + +Note that functions that use the `trait` `Contains` are no longer required +to express `A` or `B` at all: + +```rust +// Without using associated types +fn difference(container: &C) -> i32 where + C: Contains { ... } + +// Using associated types +fn difference(container: &C) -> i32 { ... } +``` + +Let's rewrite the example from the previous section using associated types: + +```rust,editable +struct Container(i32, i32); + +// A trait which checks if 2 items are stored inside of container. +// Also retrieves first or last value. +trait Contains { + // Define generic types here which methods will be able to utilize. + type A; + type B; + + fn contains(&self, &Self::A, &Self::B) -> bool; + fn first(&self) -> i32; + fn last(&self) -> i32; +} + +impl Contains for Container { + // Specify what types `A` and `B` are. If the `input` type + // is `Container(i32, i32)`, the `output` types are determined + // as `i32` and `i32`. + type A = i32; + type B = i32; + + // `&Self::A` and `&Self::B` are also valid here. + fn contains(&self, number_1: &i32, number_2: &i32) -> bool { + (&self.0 == number_1) && (&self.1 == number_2) + } + // Grab the first number. + fn first(&self) -> i32 { self.0 } + + // Grab the last number. + fn last(&self) -> i32 { self.1 } +} + +fn difference(container: &C) -> i32 { + container.last() - container.first() +} + +fn main() { + let number_1 = 3; + let number_2 = 10; + + let container = Container(number_1, number_2); + + println!("Does container contain {} and {}: {}", + &number_1, &number_2, + container.contains(&number_1, &number_2)); + println!("First number: {}", container.first()); + println!("Last number: {}", container.last()); + + println!("The difference is: {}", difference(&container)); +} +``` \ No newline at end of file diff --git a/src/generics/bounds.md b/src/generics/bounds.md index b63c350b05..0d6e29daf0 100644 --- a/src/generics/bounds.md +++ b/src/generics/bounds.md @@ -1 +1,81 @@ # Bounds + +When working with generics, the type parameters often must use traits as *bounds* to +stipulate what functionality a type implements. For example, the following +example uses the trait `Display` to print and so it requires `T` to be bound +by `Display`; that is, `T` *must* implement `Display`. + +```rust +// Define a function `printer` that takes a generic type `T` which +// must implement trait `Display`. +fn printer(t: T) { + println!("{}", t); +} +``` + +Bounding restricts the generic to types that conform to the bounds. That is: + +```rust +struct S(T); + +// Error! `Vec` does not implement `Display`. This +// specialization will fail. +let s = S(vec![1]); +``` + +Another effect of bounding is that generic instances are allowed to access the +[methods] of traits specified in the bounds. For example: + +```rust,editable +// A trait which implements the print marker: `{:?}`. +use std::fmt::Debug; + +trait HasArea { + fn area(&self) -> f64; +} + +impl HasArea for Rectangle { + fn area(&self) -> f64 { self.length * self.height } +} + +#[derive(Debug)] +struct Rectangle { length: f64, height: f64 } +#[allow(dead_code)] +struct Triangle { length: f64, height: f64 } + +// The generic `T` must implement `Debug`. Regardless +// of the type, this will work properly. +fn print_debug(t: &T) { + println!("{:?}", t); +} + +// `T` must implement `HasArea`. Any function which meets +// the bound can access `HasArea`'s function `area`. +fn area(t: &T) -> f64 { t.area() } + +fn main() { + let rectangle = Rectangle { length: 3.0, height: 4.0 }; + let _triangle = Triangle { length: 3.0, height: 4.0 }; + + print_debug(&rectangle); + println!("Area: {}", area(&rectangle)); + + //print_debug(&_triangle); + //println!("Area: {}", area(&_triangle)); + // ^ TODO: Try uncommenting these. + // | Error: Does not implement either `Debug` or `HasArea`. +} +``` + +As an additional note, [`where`][where] clauses can also be used to apply bounds in +some cases to be more expressive. + +### See also: + +[`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] + +[fmt]: /hello/print.html +[methods]: /fn/methods.html +[structs]: /custom_types/structs.html +[traits]: /trait.html +[where]: /generics/where.html \ No newline at end of file diff --git a/src/generics/bounds/testcase_empty.md b/src/generics/bounds/testcase_empty.md index 4bcf98ee78..9f7102a6ac 100644 --- a/src/generics/bounds/testcase_empty.md +++ b/src/generics/bounds/testcase_empty.md @@ -1 +1,43 @@ # Testcase: empty bounds + +A consequence of how bounds work is that even if a `trait` doesn't +include any functionality, you can still use it as a bound. `Eq` and +`Ord` are examples of such `trait`s from the `std` library. + +```rust,editable +struct Cardinal; +struct BlueJay; +struct Turkey; + +trait Red {} +trait Blue {} + +impl Red for Cardinal {} +impl Blue for BlueJay {} + +// These functions are only valid for types which implement these +// traits. The fact that the traits are empty is irrelevant. +fn red(_: &T) -> &'static str { "red" } +fn blue(_: &T) -> &'static str { "blue" } + +fn main() { + let cardinal = Cardinal; + let blue_jay = BlueJay; + let _turkey = Turkey; + + // `red()` won't work on a blue jay nor vice versa + // because of the bounds. + println!("A cardinal is {}", red(&cardinal)); + println!("A blue jay is {}", blue(&blue_jay)); + //println!("A turkey is {}", red(&_turkey)); + // ^ TODO: Try uncommenting this line. +} +``` + +### See also: + +[`std::cmp::Eq`][eq], [`std::cmp::Ord`s][ord], and [`trait`s][traits] + +[eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html +[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html +[traits]: /trait.html diff --git a/src/generics/gen_fn.md b/src/generics/gen_fn.md index 0c5faf50f8..7bbdbaae27 100644 --- a/src/generics/gen_fn.md +++ b/src/generics/gen_fn.md @@ -1 +1,59 @@ # Functions + +The same set of rules can be applied to functions: a type `T` becomes +generic when preceded by ``. + +Using generic functions sometimes requires explicitly specifying type +parameters. This may be the case if the function is called where the return type +is generic, or if the compiler doesn't have enough information to infer +the necessary type parameters. + +A function call with explicitly specified type parameters looks like: +`fun::()`. + +```rust,editable +struct A; // Concrete type `A`. +struct S(A); // Concrete type `S`. +struct SGen(T); // Generic type `SGen`. + +// The following functions all take ownership of the variable passed into +// them and immediately go out of scope, freeing the variable. + +// Define a function `reg_fn` that takes an argument `_s` of type `S`. +// This has no `` so this is not a generic function. +fn reg_fn(_s: S) {} + +// Define a function `gen_spec_t` that takes an argument `_s` of type `SGen`. +// It has been explicitly given the type parameter `A`, but because `A` has not +// been specified as a generic type parameter for `gen_spec_t`, it is not generic. +fn gen_spec_t(_s: SGen) {} + +// Define a function `gen_spec_i32` that takes an argument `_s` of type `SGen`. +// It has been explicitly given the type parameter `i32`, which is a specific type. +// Because `i32` is not a generic type, this function is also not generic. +fn gen_spec_i32(_s: SGen) {} + +// Define a function `generic` that takes an argument `_s` of type `SGen`. +// Because `SGen` is preceded by ``, this function is generic over `T`. +fn generic(_s: SGen) {} + +fn main() { + // Using the non-generic functions + reg_fn(S(A)); // Concrete type. + gen_spec_t(SGen(A)); // Implicitly specified type parameter `A`. + gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`. + + // Explicitly specified type parameter `char` to `generic()`. + generic::(SGen('a')); + + // Implicitly specified type parameter `char` to `generic()`. + generic(SGen('c')); +} +``` + +### See also: + +[functions][fn] and [`struct`s][structs] + +[fn]: /fn.html +[structs]: /custom_types/structs.html diff --git a/src/generics/gen_trait.md b/src/generics/gen_trait.md index 445d444b17..58360c02b4 100644 --- a/src/generics/gen_trait.md +++ b/src/generics/gen_trait.md @@ -1 +1,45 @@ # Traits + +Of course `trait`s can also be generic. Here we define one which reimplements +the `Drop` `trait` as a generic method to `drop` itself and an input. + +```rust,editable +// Non-copyable types. +struct Empty; +struct Null; + +// A trait generic over `T`. +trait DoubleDrop { + // Define a method on the caller type which takes an + // additional single parameter `T` and does nothing with it. + fn double_drop(self, _: T); +} + +// Implement `DoubleDrop` for any generic parameter `T` and +// caller `U`. +impl DoubleDrop for U { + // This method takes ownership of both passed arguments, + // deallocating both. + fn double_drop(self, _: T) {} +} + +fn main() { + let empty = Empty; + let null = Null; + + // Deallocate `empty` and `null`. + empty.double_drop(null); + + //empty; + //null; + // ^ TODO: Try uncommenting these lines. +} +``` + +### See also: + +[`Drop`][Drop], [`struct`][structs], and [`trait`][traits] + +[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html +[structs]: /custom_types/structs.html +[traits]: /trait.html diff --git a/src/generics/impl.md b/src/generics/impl.md index d2557ff700..0362532731 100644 --- a/src/generics/impl.md +++ b/src/generics/impl.md @@ -1 +1,52 @@ # Implementation + +Similar to functions, implementations require care to remain generic. + +```rust +struct S; // Concrete type `S` +struct GenericVal(T,); // Generic type `GenericVal` + +// impl of GenericVal where we explicitly specify type parameters: +impl GenericVal {} // Specify `f32` +impl GenericVal {} // Specify `S` as defined above + +// `` Must precede the type to remain generic +impl GenericVal {} +``` + +```rust,editable +struct Val { + val: f64 +} + +struct GenVal{ + gen_val: T +} + +// impl of Val +impl Val { + fn value(&self) -> &f64 { &self.val } +} + +// impl of GenVal for a generic type `T` +impl GenVal { + fn value(&self) -> &T { &self.gen_val } +} + +fn main() { + let x = Val { val: 3.0 }; + let y = GenVal { gen_val: 3i32 }; + + println!("{}, {}", x.value(), y.value()); +} +``` + +### See also: + +[functions returning references][fn], [`impl`][methods], and [`struct`][structs] + + +[fn]: /scope/lifetime/fn.html +[methods]: /fn/methods.html +[specialization_plans]: https://blog.rust-lang.org/2015/05/11/traits.html#the-future +[structs]: /custom_types/structs.html diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md index 807c9546f4..d282c02d75 100644 --- a/src/generics/multi_bounds.md +++ b/src/generics/multi_bounds.md @@ -1 +1,37 @@ # Multiple bounds + +Multiple bounds can be applied with a `+`. Like normal, different types are +separated with `,`. + +```rust,editable +use std::fmt::{Debug, Display}; + +fn compare_prints(t: &T) { + println!("Debug: `{:?}`", t); + println!("Display: `{}`", t); +} + +fn compare_types(t: &T, u: &U) { + println!("t: `{:?}", t); + println!("u: `{:?}", u); +} + +fn main() { + let string = "words"; + let array = [1, 2, 3]; + let vec = vec![1, 2, 3]; + + compare_prints(&string); + //compare_prints(&array); + // TODO ^ Try uncommenting this. + + compare_types(&array, &vec); +} +``` + +### See also: + +[`std::fmt`][fmt] and [`trait`s][traits] + +[fmt]: /hello/print.html +[traits]: /trait.html diff --git a/src/generics/phantom.md b/src/generics/phantom.md index f5ef5bc689..66a826bc4b 100644 --- a/src/generics/phantom.md +++ b/src/generics/phantom.md @@ -1 +1,63 @@ # Phantom type parameters + +A phantom type parameter is one that doesn't show up at runtime, +but is checked statically (and only) at compile time. + +Data types can use extra generic type parameters to act as markers +or to perform type checking at compile time. These extra parameters +hold no storage values, and have no runtime behavior. + +In the following example, we combine [std::marker::PhantomData] +with the phantom type parameter concept to create tuples containing +different data types. + +```rust,editable +use std::marker::PhantomData; + +// A phantom tuple struct which is generic over `A` with hidden parameter `B`. +#[derive(PartialEq)] // Allow equality test for this type. +struct PhantomTuple(A,PhantomData); + +// A phantom type struct which is generic over `A` with hidden parameter `B`. +#[derive(PartialEq)] // Allow equality test for this type. +struct PhantomStruct { first: A, phantom: PhantomData } + +// Note: Storage is allocated for generic type `A`, but not for `B`. +// Therefore, `B` cannot be used in computations. + +fn main() { + // Here, `f32` and `f64` are the hidden parameters. + // PhantomTuple type specified as ``. + let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); + // PhantomTuple type specified as ``. + let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); + + // Type specified as ``. + let _struct1: PhantomStruct = PhantomStruct { + first: 'Q', + phantom: PhantomData, + }; + // Type specified as ``. + let _struct2: PhantomStruct = PhantomStruct { + first: 'Q', + phantom: PhantomData, + }; + + // Compile-time Error! Type mismatch so these cannot be compared: + //println!("_tuple1 == _tuple2 yields: {}", + // _tuple1 == _tuple2); + + // Compile-time Error! Type mismatch so these cannot be compared: + //println!("_struct1 == _struct2 yields: {}", + // _struct1 == _struct2); +} +``` + +### See also: + +[Derive], [struct], and [TupleStructs] + +[Derive]: /trait/derive.html +[struct]: /custom_types/structs.html +[TupleStructs]: /custom_types/structs.html +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/src/generics/phantom/testcase_units.md b/src/generics/phantom/testcase_units.md index 012cd5c6eb..610995f87c 100644 --- a/src/generics/phantom/testcase_units.md +++ b/src/generics/phantom/testcase_units.md @@ -1 +1,88 @@ # Testcase: unit clarification + +A useful method of unit conversions can be examined by implementing `Add` +with a phantom type parameter. The `Add` `trait` is examined below: + +```rust +// This construction would impose: `Self + RHS = Output` +// where RHS defaults to Self if not specified in the implementation. +pub trait Add { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +// `Output` must be `T` so that `T + T = T`. +impl Add for T { + type Output = T; + ... +} +``` + +The whole implementation: + +```rust,editable +use std::ops::Add; +use std::marker::PhantomData; + +/// Create void enumerations to define unit types. +#[derive(Debug, Clone, Copy)] +enum Inch {} +#[derive(Debug, Clone, Copy)] +enum Mm {} + +/// `Length` is a type with phantom type parameter `Unit`, +/// and is not generic over the length type (that is `f64`). +/// +/// `f64` already implements the `Clone` and `Copy` traits. +#[derive(Debug, Clone, Copy)] +struct Length(f64, PhantomData); + +/// The `Add` trait defines the behavior of the `+` operator. +impl Add for Length { + type Output = Length; + + // add() returns a new `Length` struct containing the sum. + fn add(self, rhs: Length) -> Length { + // `+` calls the `Add` implementation for `f64`. + Length(self.0 + rhs.0, PhantomData) + } +} + +fn main() { + // Specifies `one_foot` to have phantom type parameter `Inch`. + let one_foot: Length = Length(12.0, PhantomData); + // `one_meter` has phantom type parameter `Mm`. + let one_meter: Length = Length(1000.0, PhantomData); + + // `+` calls the `add()` method we implemented for `Length`. + // + // Since `Length` implements `Copy`, `add()` does not consume + // `one_foot` and `one_meter` but copies them into `self` and `rhs`. + let two_feet = one_foot + one_foot; + let two_meters = one_meter + one_meter; + + // Addition works. + println!("one foot + one_foot = {:?} in", two_feet.0); + println!("one meter + one_meter = {:?} mm", two_meters.0); + + // Nonsensical operations fail as they should: + // Compile-time Error: type mismatch. + //let one_feter = one_foot + one_meter; +} +``` + +### See also: + +[Borrowing (`&`)], [Bounds (`X: Y`)], [enum], [impl & self], +[Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. + +[Borrowing (`&`)]: /scope/borrow.html +[Bounds (`X: Y`)]: /generics/bounds.html +[enum]: /custom_types/enum.html +[impl & self]: /fn/methods.html +[Overloading]: /trait/ops.html +[ref]: /scope/borrow/ref.html +[Traits (`X for Y`)]: /trait.html +[TupleStructs]: /custom_types/structs.html +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html diff --git a/src/generics/where.md b/src/generics/where.md index 6b877a2089..8379a0a9be 100644 --- a/src/generics/where.md +++ b/src/generics/where.md @@ -1 +1,55 @@ # Where clauses + +A bound can also be expressed using a `where` clause immediately +before the opening `{`, rather than at the type's first mention. +Additionally, `where` clauses can apply bounds to arbitrary types, +rather than just to type parameters. + +Some cases that a `where` clause is useful: + +* When specifying generic types and bounds separately is clearer: + +```rust +impl MyTrait for YourType {} + +// Expressing bounds with a `where` clause +impl MyTrait for YourType where + A: TraitB + TraitC, + D: TraitE + TraitF {} +``` + +* When using a `where` clause is more expressive than using normal syntax. +The `impl` in this example cannot be directly expressed without a `where` clause: + +```rust,editable +use std::fmt::Debug; + +trait PrintInOption { + fn print_in_option(self); +} + +// Because we would otherwise have to express this as `T: Debug` or +// use another method of indirect approach, this requires a `where` clause: +impl PrintInOption for T where + Option: Debug { + // We want `Option: Debug` as our bound because that is what's + // being printed. Doing otherwise would be using the wrong bound. + fn print_in_option(self) { + println!("{:?}", Some(self)); + } +} + +fn main() { + let vec = vec![1, 2, 3]; + + vec.print_in_option(); +} +``` + +### See also: + +[RFC][where], [`struct`][struct], and [`trait`][trait] + +[struct]: /custom_types/structs.html +[trait]: /trait.html +[where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md From ccf0e5b1296fcdf44ab9b227fe500efeb6a5ec21 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 14 Sep 2017 11:41:21 -0400 Subject: [PATCH 0651/1122] Fix tests Once https://github.com/azerupi/mdBook/pull/440 and https://github.com/azerupi/mdBook/pull/439 are merged, all tests will pass! --- src/attribute/cfg/custom.md | 2 +- src/cast.md | 4 ++-- src/crates/link.md | 2 +- src/custom_types/constants.md | 2 +- src/error/boxing_errors.md | 4 ++-- src/error/multiple_error_types.md | 2 +- src/error/option_unwrap.md | 2 +- src/error/panic.md | 4 ++-- src/error/reenter_try.md | 2 +- src/error/result.md | 2 +- src/fn/closures/closure_examples/iter_any.md | 2 +- src/fn/closures/closure_examples/iter_find.md | 2 +- src/generics.md | 8 ++++---- src/generics/assoc_items/types.md | 4 ++-- src/generics/bounds.md | 6 +++--- src/generics/phantom/testcase_units.md | 2 +- src/generics/where.md | 2 +- src/hello/print.md | 2 +- src/hello/print/fmt.md | 2 +- src/hello/print/print_display/testcase_list.md | 6 +++--- src/meta/doc.md | 4 ++-- src/meta/test.md | 2 +- src/mod/split.md | 10 +++++----- src/primitives.md | 2 +- src/primitives/array.md | 4 ++-- src/primitives/tuples.md | 2 +- src/scope/borrow.md | 4 ++-- src/scope/borrowing/freeze.md | 4 ++-- src/scope/borrowing/mut.md | 2 +- src/scope/lifetime/explicit.md | 6 +++--- src/std/hash/hashset.md | 2 +- src/std/option.md | 4 ++-- src/std/panic.md | 2 +- src/std/result.md | 4 ++-- src/std/result/try.md | 2 +- src/std/vec.md | 2 +- src/std_misc/ffi.md | 6 +++--- src/std_misc/file/create.md | 2 +- src/std_misc/file/open.md | 2 +- src/std_misc/fs.md | 4 ++-- src/std_misc/process/pipe.md | 4 ++-- src/std_misc/process/wait.md | 2 +- src/variable_bindings/declare.md | 2 +- src/variable_bindings/mut.md | 2 +- src/variable_bindings/scope.md | 2 +- 45 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/attribute/cfg/custom.md b/src/attribute/cfg/custom.md index 2e2bc419a5..371aea26ad 100644 --- a/src/attribute/cfg/custom.md +++ b/src/attribute/cfg/custom.md @@ -3,7 +3,7 @@ Some conditionals like `target_os` are implicitly provided by `rustc`, but custom conditionals must be passed to `rustc` using the `--cfg` flag. -```rust,editable +```rust,editable,ignore,mdbook-runnable #[cfg(some_condition)] fn conditional_function() { println!("condition met!") diff --git a/src/cast.md b/src/cast.md index 5b0a3f5525..849afdcb66 100644 --- a/src/cast.md +++ b/src/cast.md @@ -7,7 +7,7 @@ Rules for converting between integral types follow C conventions generally, except in cases where C has undefined behavior. The behavior of all casts between integral types is well defined in Rust. -```rust,editable +```rust,editable,ignore,mdbook-runnable // Suppress all warnings from casts which overflow. #![allow(overflowing_literals)] @@ -56,4 +56,4 @@ fn main() { // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); } -``` \ No newline at end of file +``` diff --git a/src/crates/link.md b/src/crates/link.md index c7eabdbfbd..b5ab01d999 100644 --- a/src/crates/link.md +++ b/src/crates/link.md @@ -5,7 +5,7 @@ used. This will not only link the library, but also import all its items under a module named the same as the library. The visibility rules that apply to modules also apply to libraries. -```rust,editable +```rust,ignore // Link to `library`, import items under the `rary` module extern crate rary; diff --git a/src/custom_types/constants.md b/src/custom_types/constants.md index eaaa8340b7..63cc7f00ef 100644 --- a/src/custom_types/constants.md +++ b/src/custom_types/constants.md @@ -13,7 +13,7 @@ types must be specifically annotated so that they fulfill the `'static` lifetime. This may seem minor though because the required explicit annotation hides the distinction. -```rust,editable +```rust,editable,ignore,mdbook-runnable // Globals are declared outside all other scopes. static LANGUAGE: &'static str = "Rust"; const THRESHOLD: i32 = 10; diff --git a/src/error/boxing_errors.md b/src/error/boxing_errors.md index 9c7bcd5991..48a0b5bf51 100644 --- a/src/error/boxing_errors.md +++ b/src/error/boxing_errors.md @@ -8,7 +8,7 @@ The `std` library automatically converts any type that implements the `Error` trait into the trait object `Box`, via `From`. To a library user, this conveniently allows the following: -```rust +```rust,ignore fn foo(...) -> Result> { ... } ``` @@ -24,7 +24,7 @@ underlying error type is only known at runtime and not [statically determined][dynamic_dispatch]. As mentioned above, all that needs to be done is to implement the `Error` trait: -```rust +```rust,ignore trait Error: Debug + Display { fn description(&self) -> &str; fn cause(&self) -> Option<&Error>; diff --git a/src/error/multiple_error_types.md b/src/error/multiple_error_types.md index a25bdfacc4..01e5b9b639 100644 --- a/src/error/multiple_error_types.md +++ b/src/error/multiple_error_types.md @@ -12,7 +12,7 @@ In the following code, two instances of `unwrap` generate different error types. `Vec::first` returns an `Option`, while `parse::` returns a `Result`: -```rust +```rust,ignore fn double_first(vec: Vec<&str>) -> i32 { let first = vec.first().unwrap(); // Generate error 1 2 * first.parse::().unwrap() // Generate error 2 diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md index f1d8ccd9a9..e5760d4e98 100644 --- a/src/error/option_unwrap.md +++ b/src/error/option_unwrap.md @@ -23,7 +23,7 @@ but `unwrap` otherwise leaves us with a less meaningful output than explicit handling. In the following example, explicit handling yields a more controlled result while retaining the option to `panic` if desired. -```rust,editable +```rust,editable,ignore,mdbook-runnable // The commoner has seen it all, and can handle any gift well. // All gifts are handled explicitly using `match`. fn give_commoner(gift: Option<&str>) { diff --git a/src/error/panic.md b/src/error/panic.md index 2a38f96351..1888d8a78a 100644 --- a/src/error/panic.md +++ b/src/error/panic.md @@ -4,7 +4,7 @@ The simplest error handling mechanism we will see is `panic`. It prints an error message, starts unwinding the task, and usually exits the program. Here, we explicitly call `panic` on our error condition: -```rust,editable +```rust,editable,ignore,mdbook-runnable fn give_princess(gift: &str) { // Princesses hate snakes, so we need to stop if she disapproves! if gift == "snake" { panic!("AAAaaaaa!!!!"); } @@ -16,4 +16,4 @@ fn main() { give_princess("teddy bear"); give_princess("snake"); } -``` \ No newline at end of file +``` diff --git a/src/error/reenter_try.md b/src/error/reenter_try.md index c9151a511e..cb6ae1cd31 100644 --- a/src/error/reenter_try.md +++ b/src/error/reenter_try.md @@ -4,7 +4,7 @@ Notice in the previous example that our immediate reaction to calling `parse` is to `map` the error from a library error into our new custom error type: -```rust +```rust,ignore .and_then(|s| s.parse::()) .map_err(DoubleError::Parse) ``` diff --git a/src/error/result.md b/src/error/result.md index 6e1b504f73..be10b8ad96 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -21,7 +21,7 @@ be possible to parse a string into the other type, so `parse()` returns a Let's see what happens when we successfully and unsuccessfully `parse()` a string: -```rust,editable +```rust,editable,ignore,mdbook-runnable fn double_number(number_str: &str) -> i32 { // Let's try using `unwrap()` to get the number out. Will it bite us? 2 * number_str.parse::().unwrap() diff --git a/src/fn/closures/closure_examples/iter_any.md b/src/fn/closures/closure_examples/iter_any.md index fc171d2bc7..65078540ee 100644 --- a/src/fn/closures/closure_examples/iter_any.md +++ b/src/fn/closures/closure_examples/iter_any.md @@ -4,7 +4,7 @@ `true` if any element satisfies the predicate. Otherwise `false`. Its signature: -```rust +```rust,ignore pub trait Iterator { // The type being iterated over. type Item; diff --git a/src/fn/closures/closure_examples/iter_find.md b/src/fn/closures/closure_examples/iter_find.md index 1dc4ce8c3e..77ddad2ce5 100644 --- a/src/fn/closures/closure_examples/iter_find.md +++ b/src/fn/closures/closure_examples/iter_find.md @@ -4,7 +4,7 @@ the first element which satisfies the predicate as an `Option`. Its signature: -```rust +```rust,ignore pub trait Iterator { // The type being iterated over. type Item; diff --git a/src/generics.md b/src/generics.md index fbe75d42b1..9c3f97397d 100644 --- a/src/generics.md +++ b/src/generics.md @@ -16,12 +16,12 @@ generic type parameter is generic, and everything else is concrete (non-generic) For example, defining a *generic function* named `foo` that takes an argument `T` of any type: -```rust -fn foo(T) { ... } +```rust,ignore +fn foo(arg: T) { ... } ``` Because `T` has been specified as a generic type parameter using ``, it -is considered generic when used here as `(T)`. This is the case even if `T` +is considered generic when used here as `(arg: T)`. This is the case even if `T` has previously been defined as a `struct`. This example shows some of the syntax in action: @@ -61,4 +61,4 @@ fn main() { [`struct`s][structs] [structs]: /custom_types/structs.html -[camelcase]: https://en.wikipedia.org/wiki/CamelCase \ No newline at end of file +[camelcase]: https://en.wikipedia.org/wiki/CamelCase diff --git a/src/generics/assoc_items/types.md b/src/generics/assoc_items/types.md index 419aa4c596..25196f2e0e 100644 --- a/src/generics/assoc_items/types.md +++ b/src/generics/assoc_items/types.md @@ -20,7 +20,7 @@ trait Contains { Note that functions that use the `trait` `Contains` are no longer required to express `A` or `B` at all: -```rust +```rust,ignore // Without using associated types fn difference(container: &C) -> i32 where C: Contains { ... } @@ -82,4 +82,4 @@ fn main() { println!("The difference is: {}", difference(&container)); } -``` \ No newline at end of file +``` diff --git a/src/generics/bounds.md b/src/generics/bounds.md index 0d6e29daf0..f8d73e42df 100644 --- a/src/generics/bounds.md +++ b/src/generics/bounds.md @@ -5,7 +5,7 @@ stipulate what functionality a type implements. For example, the following example uses the trait `Display` to print and so it requires `T` to be bound by `Display`; that is, `T` *must* implement `Display`. -```rust +```rust,ignore // Define a function `printer` that takes a generic type `T` which // must implement trait `Display`. fn printer(t: T) { @@ -15,7 +15,7 @@ fn printer(t: T) { Bounding restricts the generic to types that conform to the bounds. That is: -```rust +```rust,ignore struct S(T); // Error! `Vec` does not implement `Display`. This @@ -78,4 +78,4 @@ some cases to be more expressive. [methods]: /fn/methods.html [structs]: /custom_types/structs.html [traits]: /trait.html -[where]: /generics/where.html \ No newline at end of file +[where]: /generics/where.html diff --git a/src/generics/phantom/testcase_units.md b/src/generics/phantom/testcase_units.md index 610995f87c..3df6504b6c 100644 --- a/src/generics/phantom/testcase_units.md +++ b/src/generics/phantom/testcase_units.md @@ -3,7 +3,7 @@ A useful method of unit conversions can be examined by implementing `Add` with a phantom type parameter. The `Add` `trait` is examined below: -```rust +```rust,ignore // This construction would impose: `Self + RHS = Output` // where RHS defaults to Self if not specified in the implementation. pub trait Add { diff --git a/src/generics/where.md b/src/generics/where.md index 8379a0a9be..483843350f 100644 --- a/src/generics/where.md +++ b/src/generics/where.md @@ -9,7 +9,7 @@ Some cases that a `where` clause is useful: * When specifying generic types and bounds separately is clearer: -```rust +```rust,ignore impl MyTrait for YourType {} // Expressing bounds with a `where` clause diff --git a/src/hello/print.md b/src/hello/print.md index 6dae4d7037..93357f732e 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -10,7 +10,7 @@ some of which include: All parse text in the same fashion. A plus is that the formatting correctness will be checked at compile time. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { // In general, the `{}` will be automatically replaced with any // arguments. These will be stringified. diff --git a/src/hello/print/fmt.md b/src/hello/print/fmt.md index 4a38dab0f8..e47757b464 100644 --- a/src/hello/print/fmt.md +++ b/src/hello/print/fmt.md @@ -72,7 +72,7 @@ types in the [`std::fmt`][fmt] documentation. Add an implementation of the `fmt::Display` trait for the `Color` struct above so that the output displays as: -``` +```text RGB (128, 255, 90) 0x80FF5A RGB (0, 3, 254) 0x0003FE RGB (0, 0, 0) 0x000000 diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index 52dab44b2b..8246384b49 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -8,7 +8,7 @@ results. Rust provides the `try!` macro and alternatively the equivalent Using `try!` on `write!` looks like this: -```rust +```rust,ignore // Try `write!` to see if it errors. If it errors, return // the error. Otherwise continue. try!(write!(f, "{}", value)); @@ -16,7 +16,7 @@ try!(write!(f, "{}", value)); The `?` shorthand alternative looks like this: -```rust +```rust,ignore write!(f, "{}", value)?; ``` @@ -61,7 +61,7 @@ fn main() { Try changing the program so that the index of each element in the vector is also printed. The new output should look like this: -```rust +```rust,ignore [0: 1, 1: 2, 2: 3] ``` diff --git a/src/meta/doc.md b/src/meta/doc.md index 0c574462e3..4a49c2f160 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -4,7 +4,7 @@ Doc comments are very useful for big projects that require documentation. When running [Rustdoc][1], these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown][2]. -```rust,editable +```rust,editable,ignore,mdbook-runnable #![crate_name = "doc"] /// A human being is represented here @@ -61,4 +61,4 @@ $ rustdoc --test --extern doc="libdoc.rlib" doc.rs generate and run the correct rustc and rustdoc commands.) [1]: https://doc.rust-lang.org/book/documentation.html -[2]: https://en.wikipedia.org/wiki/Markdown \ No newline at end of file +[2]: https://en.wikipedia.org/wiki/Markdown diff --git a/src/meta/test.md b/src/meta/test.md index 8eb410f287..e93b425dea 100644 --- a/src/meta/test.md +++ b/src/meta/test.md @@ -52,7 +52,7 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured If `--test` were not included, then this would happen -``` +```bash $ rustc unit_test.rs $ ./unit_test If you see this, the tests were not compiled nor ran! diff --git a/src/mod/split.md b/src/mod/split.md index b6a0ede8ce..a344c4f97e 100644 --- a/src/mod/split.md +++ b/src/mod/split.md @@ -15,7 +15,7 @@ $ tree . In `split.rs`: -```rust +```rust,ignore // This declaration will look for a file named `my.rs` or `my/mod.rs` and will // insert its contents inside a module named `my` under this scope mod my; @@ -38,7 +38,7 @@ fn main() { In `my/mod.rs`: -```rust +```rust,ignore // Similarly `mod inaccessible` and `mod nested` will locate the `nested.rs` // and `inaccessible.rs` files and insert them here under their respective // modules @@ -62,7 +62,7 @@ pub fn indirect_access() { In `my/nested.rs`: -```rust +```rust,ignore pub fn function() { println!("called `my::nested::function()`"); } @@ -75,7 +75,7 @@ fn private_function() { In `my/inaccessible.rs`: -```rust +```rust,ignore #[allow(dead_code)] pub fn public_function() { println!("called `my::inaccessible::public_function()`"); @@ -93,4 +93,4 @@ called `my::indirect_access()`, that called `my::nested::function()` ``` -[visibility]: /mod/visibility.html \ No newline at end of file +[visibility]: /mod/visibility.html diff --git a/src/primitives.md b/src/primitives.md index be1721eb95..b7e01cb85f 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -15,7 +15,7 @@ Variables can always be *type annotated*. Numbers may additionally be annotated via a *suffix* or *by default*. Integers default to `i32` and floats to `f64`. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { // Variables can be type annotated. let logical: bool = true; diff --git a/src/primitives/array.md b/src/primitives/array.md index 16edd2a0dd..6c0fda962c 100644 --- a/src/primitives/array.md +++ b/src/primitives/array.md @@ -11,7 +11,7 @@ usize, determined by the processor architecture eg 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature `&[T]`. -```rust,editable +```rust,editable,ignore,mdbook-runnable use std::mem; // This function borrows a slice @@ -48,4 +48,4 @@ fn main() { // Out of bound indexing yields a panic println!("{}", xs[5]); } -``` \ No newline at end of file +``` diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index 10e089bff6..3d6835ed7c 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -73,7 +73,7 @@ fn main() { accepts a matrix as an argument, and returns a matrix in which two elements have been swapped. For example: - ```rust + ```rust,ignore println!("Matrix:\n{}", matrix); println!("Transpose:\n{}", transpose(matrix)); ``` diff --git a/src/scope/borrow.md b/src/scope/borrow.md index 59a655fc0b..c3e65e251b 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -8,7 +8,7 @@ The compiler statically guarantees (via its borrow checker) that references *always* point to valid objects. That is, while references to an object exist, the object cannot be destroyed. -```rust,editable +```rust,editable,ignore,mdbook-runnable // This function takes ownership of a box and destroys it fn eat_box_i32(boxed_i32: Box) { println!("Destroying box that contains {}", boxed_i32); @@ -44,4 +44,4 @@ fn main() { // `boxed_i32` can now give up ownership to `eat_box` and be destroyed eat_box_i32(boxed_i32); } -``` \ No newline at end of file +``` diff --git a/src/scope/borrowing/freeze.md b/src/scope/borrowing/freeze.md index e3123b6df5..29f2d71fb1 100644 --- a/src/scope/borrowing/freeze.md +++ b/src/scope/borrowing/freeze.md @@ -3,7 +3,7 @@ When data is immutably borrowed, it also *freezes*. *Frozen* data can't be modified via the original object until all references to it go out of scope: -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { let mut _mutable_integer = 7i32; @@ -21,4 +21,4 @@ fn main() { // Ok! `_mutable_integer` is not frozen in this scope _mutable_integer = 3; } -``` \ No newline at end of file +``` diff --git a/src/scope/borrowing/mut.md b/src/scope/borrowing/mut.md index 82444d5f8a..282154614e 100644 --- a/src/scope/borrowing/mut.md +++ b/src/scope/borrowing/mut.md @@ -5,7 +5,7 @@ a *mutable reference* and gives read/write access to the borrower. In contrast, `&T` borrows the data via an immutable reference, and the borrower can read the data but not modify it: -```rust,editable +```rust,editable,ignore,mdbook-runnable #[allow(dead_code)] #[derive(Clone, Copy)] struct Book { diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md index a934900033..57941f1b1b 100644 --- a/src/scope/lifetime/explicit.md +++ b/src/scope/lifetime/explicit.md @@ -6,7 +6,7 @@ elided[^1], Rust requires explicit annotations to determine what the lifetime of a reference should be. The syntax for explicitly annotating a lifetime uses an apostrophe character as follows: -```rust +```rust,ignore foo<'a> // `foo` has a lifetime parameter `'a` ``` @@ -18,7 +18,7 @@ may not exceed that of `'a`. Explicit annotation of a type has the form In cases with multiple lifetimes, the syntax is similar: -```rust +```rust,ignore foo<'a, 'b> // `foo` has lifetime parameters `'a` and `'b` ``` @@ -27,7 +27,7 @@ In this case, the lifetime of `foo` cannot exceed that of either `'a` *or* `'b`. See the following example for explicit lifetime annotation in use: -```rust,editable +```rust,editable,ignore,mdbook-runnable // `print_refs` takes two references to `i32` which have different // lifetimes `'a` and `'b`. These two lifetimes must both be at // least as long as the function `print_refs`. diff --git a/src/std/hash/hashset.md b/src/std/hash/hashset.md index fbf6197590..3d83717501 100644 --- a/src/std/hash/hashset.md +++ b/src/std/hash/hashset.md @@ -32,7 +32,7 @@ get all the elements that are in one set or the other, but *not* both. Try all of these in the following example. -```rust,editable +```rust,editable,ignore,mdbook-runnable use std::collections::HashSet; fn main() { diff --git a/src/std/option.md b/src/std/option.md index 569d4721a8..30927e87ea 100644 --- a/src/std/option.md +++ b/src/std/option.md @@ -8,7 +8,7 @@ The `Option` enum has two variants: * `None`, to indicate failure or lack of value, and * `Some(value)`, a tuple struct that wraps a `value` with type `T`. -```rust,editable +```rust,editable,ignore,mdbook-runnable // An integer division that doesn't `panic!` fn checked_division(dividend: i32, divisor: i32) -> Option { if divisor == 0 { @@ -47,4 +47,4 @@ fn main() { // Unwrapping a `None` variant will `panic!` println!("{:?} unwraps to {:?}", none, none.unwrap()); } -``` \ No newline at end of file +``` diff --git a/src/std/panic.md b/src/std/panic.md index 6e6d3e61ee..cf220e8203 100644 --- a/src/std/panic.md +++ b/src/std/panic.md @@ -7,7 +7,7 @@ resources *owned* by the thread by calling the destructor of all its objects. Since we are dealing with programs with only one thread, `panic!` will cause the program to report the panic message and exit. -```rust,editable +```rust,editable,ignore,mdbook-runnable // Re-implementation of integer division (/) fn division(dividend: i32, divisor: i32) -> i32 { if divisor == 0 { diff --git a/src/std/result.md b/src/std/result.md index 37e849c5e2..b812b9de99 100644 --- a/src/std/result.md +++ b/src/std/result.md @@ -12,7 +12,7 @@ The `Result` enum has two variants: * `Err(why)`, which indicates that the operation failed, and wraps `why`, which (hopefully) explains the cause of the failure. (`why` has type `E`) -```rust,editable +```rust,editable,ignore,mdbook-runnable mod checked { // Mathematical "errors" we want to catch #[derive(Debug)] @@ -71,4 +71,4 @@ fn main() { // Will this fail? println!("{}", op(1.0, 10.0)); } -``` \ No newline at end of file +``` diff --git a/src/std/result/try.md b/src/std/result/try.md index d93fed5874..6349387519 100644 --- a/src/std/result/try.md +++ b/src/std/result/try.md @@ -5,7 +5,7 @@ can be used to make things pretty again. The `try!` macro expands to a match expression, where the `Err(err)` branch expands to an early `return Err(err)`, and the `Ok(ok)` branch expands to an `ok` expression. -```rust,editable +```rust,editable,ignore,mdbook-runnable mod checked { #[derive(Debug)] enum MathError { diff --git a/src/std/vec.md b/src/std/vec.md index 3a2ac228c3..2ad8338be5 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -7,7 +7,7 @@ indicates how much memory is reserved for the vector. The vector can grow as long as the length is smaller than the capacity. When this threshold needs to be surpassed, the vector is reallocated with a larger capacity. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { // Iterators can be collected into vectors let collected_iterator: Vec = (0..10).collect(); diff --git a/src/std_misc/ffi.md b/src/std_misc/ffi.md index baddf05ab7..84b1742cb5 100644 --- a/src/std_misc/ffi.md +++ b/src/std_misc/ffi.md @@ -4,7 +4,7 @@ Rust provides a Foreign Function Interface (FFI) to C libraries. Foreign functions must be declared inside an `extern` block annotated with a `#[link]` attribute containing the name of the foreign library. -```rust,editable +```rust,ignore use std::fmt; // this extern block links to the libm library @@ -49,7 +49,7 @@ impl fmt::Debug for Complex { Since calling foreign functions is considered unsafe, it's common to write safe wrappers around them. -```rust,editable +```rust,ignore use std::fmt; #[link(name = "m")] @@ -86,4 +86,4 @@ impl fmt::Debug for Complex { } } } -``` \ No newline at end of file +``` diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md index 495c1c40a3..889d52fe58 100644 --- a/src/std_misc/file/create.md +++ b/src/std_misc/file/create.md @@ -4,7 +4,7 @@ The `create` static method opens a file in write-only mode. If the file already existed, the old content is destroyed. Otherwise, a new file is created. -```rust,editable +```rust,ignore static LOREM_IPSUM: &'static str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, diff --git a/src/std_misc/file/open.md b/src/std_misc/file/open.md index 8871c2b591..2848b076e1 100644 --- a/src/std_misc/file/open.md +++ b/src/std_misc/file/open.md @@ -5,7 +5,7 @@ The `open` static method can be used to open a file in read-only mode. A `File` owns a resource, the file descriptor and takes care of closing the file when it is `drop`ed. -```rust,editable +```rust,editable,ignore use std::error::Error; use std::fs::File; use std::io::prelude::*; diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index 6299f5e804..abc1b92967 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -3,7 +3,7 @@ The `std::io::fs` module contains several functions that deal with the filesystem. -```rust,editable +```rust,ignore use std::fs; use std::fs::{File, OpenOptions}; use std::io; @@ -119,7 +119,7 @@ $ rustc fs.rs && ./fs And the final state of the `a` directory is: -``` +```text $ tree a a |-- b.txt diff --git a/src/std_misc/process/pipe.md b/src/std_misc/process/pipe.md index 711ac60b40..aeba29d2f5 100644 --- a/src/std_misc/process/pipe.md +++ b/src/std_misc/process/pipe.md @@ -4,7 +4,7 @@ The `std::Child` struct represents a running child process, and exposes the `stdin`, `stdout` and `stderr` handles for interaction with the underlying process via pipes. -```rust,editable +```rust,ignore use std::error::Error; use std::io::prelude::*; use std::process::{Command, Stdio}; @@ -46,4 +46,4 @@ fn main() { Ok(_) => print!("wc responded with:\n{}", s), } } -``` \ No newline at end of file +``` diff --git a/src/std_misc/process/wait.md b/src/std_misc/process/wait.md index a80378e2fc..5445ce45fa 100644 --- a/src/std_misc/process/wait.md +++ b/src/std_misc/process/wait.md @@ -3,7 +3,7 @@ If you'd like to wait for a `process::Child` to finish, you must call `Child::wait`, which will return a `process::ExitStatus`. -```rust,editable +```rust,ignore use std::process::Command; fn main() { diff --git a/src/variable_bindings/declare.md b/src/variable_bindings/declare.md index 574eb6f71c..e9dee6a132 100644 --- a/src/variable_bindings/declare.md +++ b/src/variable_bindings/declare.md @@ -4,7 +4,7 @@ It's possible to declare variable bindings first, and initialize them later. However, this form is seldom used, as it may lead to the use of uninitialized variables. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { // Declare a variable binding let a_binding; diff --git a/src/variable_bindings/mut.md b/src/variable_bindings/mut.md index 5a1f1eb9ab..0925132f20 100644 --- a/src/variable_bindings/mut.md +++ b/src/variable_bindings/mut.md @@ -3,7 +3,7 @@ Variable bindings are immutable by default, but this can be overridden using the `mut` modifier. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; diff --git a/src/variable_bindings/scope.md b/src/variable_bindings/scope.md index a29268b801..d9639b42e3 100644 --- a/src/variable_bindings/scope.md +++ b/src/variable_bindings/scope.md @@ -4,7 +4,7 @@ Variable bindings have a scope, and are constrained to live in a *block*. A block is a collection of statements enclosed by braces `{}`. Also, [variable shadowing][variable-shadow] is allowed. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { // This binding lives in the main function let long_lived_binding = 1; From 24fb8d45d2d09d3fc996c9a3454767fee82cb403 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 14 Sep 2017 12:59:03 -0400 Subject: [PATCH 0652/1122] Bring back deploy machinery --- .travis.yml | 3 +++ deploy.sh | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 deploy.sh diff --git a/.travis.yml b/.travis.yml index 8b74cb0f43..9b2b10319a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,7 @@ branches: before_script: - (cargo install mdbook --git https://github.com/azerupi/mdBook.git --force || true) script: + - mdbook build - mdbook test +after_success: + - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000000..358ba9a37e --- /dev/null +++ b/deploy.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +rev=$(git rev-parse --short HEAD) + +cd book + +git init +git config user.name "Steve Klabnik" +git config user.email "steve@steveklabnik.com" +git remote add upstream "https://$GITHUB_TOKEN@github.com/rust-lang/rust-by-example.git" +git fetch upstream && git reset upstream/gh-pages + +echo "rustbyexample.com" > CNAME + +touch . + +git add -A . + +git commit -m "rebuild pages at ${rev}" +git push -q upstream HEAD:gh-pages From cce99fa047470c772fa52aae8f16799d13e088a2 Mon Sep 17 00:00:00 2001 From: Anthony Defranceschi Date: Thu, 14 Sep 2017 13:50:08 -0400 Subject: [PATCH 0653/1122] Fix a broken search/replace in std_misc/path In https://github.com/rust-lang/rust-by-example/pull/883 an error was committed, this fixes it. --- src/std_misc/path.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/std_misc/path.md b/src/std_misc/path.md index e753e29c7f..ae66529c6b 100644 --- a/src/std_misc/path.md +++ b/src/std_misc/path.md @@ -5,8 +5,7 @@ two flavors of `Path`: `posix::Path`, for UNIX-like systems, and `windows::Path`, for Windows. The prelude exports the appropriate platform-specific `Path` variant. -A `Path` can be created from almost any type that implements the -`OsStr` trait, like a string, and provides several methods to get +A `Path` can be created from an `OsStr`, and provides several methods to get information from the file/directory the path points to. Note that a `Path` is *not* internally represented as an UTF-8 string, but From 0084279886e81361767f651da13602be4c2df7cf Mon Sep 17 00:00:00 2001 From: Anna Liao Date: Thu, 14 Sep 2017 13:52:40 -0400 Subject: [PATCH 0654/1122] fs: add alternative format for ? notation --- src/std_misc/fs.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index abc1b92967..2f06c3e226 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -129,6 +129,17 @@ a 1 directory, 2 files ``` +An alternative way to define the function `cat` is with `?` notation: + +```rust,ignore +fn cat(path: &Path) -> io::Result { + let mut f = File::open(path)?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + Ok(s) +} +``` + ### See also: [`cfg!`][cfg] From dd6dba890a751b95a1658b83fae3d5e8d0124eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 14 Sep 2017 21:37:26 +0300 Subject: [PATCH 0655/1122] Fix typo: Litearls -> Literals --- src/SUMMARY.md | 4 ++-- src/primitives/literals.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 637ebed971..4d2e76542f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -11,7 +11,7 @@ - [Formatting](hello/print/fmt.md) - [Primitives](primitives.md) - - [Litearls and operators](primitives/literals.md) + - [Literals and operators](primitives/literals.md) - [Tuples](primitives/tuples.md) - [Arrays and Slices](primitives/array.md) @@ -176,4 +176,4 @@ - [Documentation](meta/doc.md) - [Testing](meta/test.md) -- [Unsafe Operations](unsafe.md) \ No newline at end of file +- [Unsafe Operations](unsafe.md) diff --git a/src/primitives/literals.md b/src/primitives/literals.md index 0a45612e52..1f27ac4ee6 100644 --- a/src/primitives/literals.md +++ b/src/primitives/literals.md @@ -1,4 +1,4 @@ -# Litearls and operators +# Literals and operators Integers `1`, floats `1.2`, characters `'a'`, strings `"abc"`, booleans `true` and the unit type `()` can be expressed using literals. From 3898abc78879693d0f6133378271a12d7e27bf1e Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 14 Sep 2017 16:03:36 -0400 Subject: [PATCH 0656/1122] Fix URLs for borrowing sub-sections I made a mistake when porting. --- src/SUMMARY.md | 8 ++++---- src/scope/{borrowing => borrow}/alias.md | 0 src/scope/{borrowing => borrow}/freeze.md | 0 src/scope/{borrowing => borrow}/mut.md | 0 src/scope/{borrowing => borrow}/ref.md | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename src/scope/{borrowing => borrow}/alias.md (100%) rename src/scope/{borrowing => borrow}/freeze.md (100%) rename src/scope/{borrowing => borrow}/mut.md (100%) rename src/scope/{borrowing => borrow}/ref.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 637ebed971..a6145008cc 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -102,10 +102,10 @@ - [Ownership and moves](scope/move.md) - [Mutability](scope/move/mut.md) - [Borrowing](scope/borrow.md) - - [Mutability](scope/borrowing/mut.md) - - [Freezing](scope/borrowing/freeze.md) - - [Aliasing](scope/borrowing/alias.md) - - [The ref pattern](scope/borrowing/ref.md) + - [Mutability](scope/borrow/mut.md) + - [Freezing](scope/borrow/freeze.md) + - [Aliasing](scope/borrow/alias.md) + - [The ref pattern](scope/borrow/ref.md) - [Lifetimes](scope/lifetime.md) - [Explicit annotation](scope/lifetime/explicit.md) - [Functions](scope/lifetime/fn.md) diff --git a/src/scope/borrowing/alias.md b/src/scope/borrow/alias.md similarity index 100% rename from src/scope/borrowing/alias.md rename to src/scope/borrow/alias.md diff --git a/src/scope/borrowing/freeze.md b/src/scope/borrow/freeze.md similarity index 100% rename from src/scope/borrowing/freeze.md rename to src/scope/borrow/freeze.md diff --git a/src/scope/borrowing/mut.md b/src/scope/borrow/mut.md similarity index 100% rename from src/scope/borrowing/mut.md rename to src/scope/borrow/mut.md diff --git a/src/scope/borrowing/ref.md b/src/scope/borrow/ref.md similarity index 100% rename from src/scope/borrowing/ref.md rename to src/scope/borrow/ref.md From cf280c3f02965b3b869a259999227c8abbdbee15 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 14 Sep 2017 16:17:41 -0400 Subject: [PATCH 0657/1122] Fix heading in flow_control\for --- src/flow_control/for.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 21f9ac22b4..0d5f4fc559 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -24,8 +24,8 @@ fn main() { } ``` -###See also +### See also [Iterator][iter] -[iter]: /trait/iter.html \ No newline at end of file +[iter]: /trait/iter.html From d562e1bc463186d30b9e0cbf33d9fb98bf70d136 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 14 Sep 2017 17:43:55 -0400 Subject: [PATCH 0658/1122] Add back in meta info --- CODE_OF_CONDUCT.md | 38 ++++++++++++++++++++++++++++ CONTRIBUTING.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++ README.md | 31 +++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 README.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..1a72217d41 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,38 @@ +# The Rust Code of Conduct + +## Conduct + +**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org) + +* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. +* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. +* Please be kind and courteous. There's no need to be mean or rude. +* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. +* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. + +## Moderation + + +These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team]. + +1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) +2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. +3. Moderators will first respond to such remarks with a warning. +4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. +5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. +6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. +7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. +8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. + +In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. + +And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. + +The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. + +*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/).* + +[Rust moderation team]: https://www.rust-lang.org/en-US/team.html#Moderation-team diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..7afd6d7057 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,63 @@ +# Rust by Example contribution guidelines + +Thank you for your interest in making Rust by Example (also known as RBE) +better! We'd love to have your contribution. We expect all contributors to +abide by the [Rust code of conduct], which you can find at that link or in the +[`CODE_OF_CONDUCT.md`] file in this repository. + +[Rust code of conduct]: https://www.rust-lang.org/en-US/conduct.html +[`CODE_OF_CONDUCT.md`]: https://github.com/rust-lang/rust-by-example/blob/master/CODE_OF_CONDUCT.md + +## License + +RBE is dual licenced under the MIT and Apache 2.0 licenses, and so are all +contributions. Please see the [`LICENSE-MIT`] and [`LICENSE-APACHE`] files in +this directory for more details. + +[`LICENSE-MIT`]: https://github.com/rust-lang/rust-by-example/blob/master/LICENSE-MIT +[`LICENSE-APACHE`]: https://github.com/rust-lang/rust-by-example/blob/master/LICENSE-APACHE + +## Pull Requests + +To make changes to RBE, please send in pull requests on GitHub to the `master` +branch. We'll review them and either merge or request changes. Travis CI tests +everything as well, so you may get feedback from it too. + +If you make additions or other changes to a pull request, feel free to either amend +previous commits or only add new ones, however you prefer. We may ask you to squash +your commits before merging, depending. + + +## Issue Tracker + +You can find the issue tracker [on +GitHub](https://github.com/rust-lang/rust-by-example/issues). If you've found a +problem with RBE, please open an issue there. + +Information about labels is coming soon! + +## Development workflow + +To build RBE, [install Rust], and then: + +```bash +> git clone https://github.com/rust-lang/rust-by-example +> cd rust-by-example +> cargo install mdbook +> mdbook build +``` + +[install Rust]: http://rust-lang.org/install.html + +The files will be in the `book` directory at the top-level; `mdbook open` will +open the contents in your web browser. + +To run the tests: + +```bash +> mdbook test +``` + +If you're adding a new chapter, you'll need to edit `src\SUMMARY.md` to add it. If +you're tweaking an existing example, you'll need to edit the corresponding file; check +`src\SUMMARY.md` to see a mapping of where chapters go to files. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..82805f2337 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Rust By Example + +[![Build Status](https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master)](https://travis-ci.org/rust-lang/rust-by-example) + +Learn Rust with examples (Live code editor included) + +## Using + +If you'd like to read Rust by Example, you can visit +[https://rustbyexample.com/][] to read it online. + +If you'd like to read it locally, [install Rust], and then: + +```bash +> git clone https://github.com/rust-lang/rust-by-example +> cd rust-by-example +> cargo install mdbook +> mdbook build +> mdbook open +``` + +[install Rust]: http://rust-lang.org/install.html + +To be able to run the examples, you must be connected to the internet; you can +read all content offline, however! + +## Contributing + +Please see the [CONTRIBUTING.md] file for more details. + +[CONTRIBUTING.md]: https://github.com/rust-lang/rust-by-example/blob/master/CONTRIBUTING.md From 111a4db69f190416f2e5c3dd2dc7fc8dda4c09da Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 14 Sep 2017 17:09:35 -0600 Subject: [PATCH 0659/1122] New `Iter` section in Error Chapter. Inspired by [Karol's blog post](http://xion.io/post/code/rust-iter-patterns.html). Tested by visually inspecting the pages served by `mdbook serve` and running each of the blocks of code. Fixes #895. --- src/SUMMARY.md | 1 + src/error/iter_result.md | 81 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/error/iter_result.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4d2e76542f..d467a0bc10 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -143,6 +143,7 @@ - [Defining an error type](error/define_error_type.md) - [Other uses of `try!`](error/reenter_try.md) - [`Box`ing errors](error/boxing_errors.md) + - [`Iter>`](error/iter_result.md) - [Std library types](std.md) - [Box, stack and heap](std/box.md) diff --git a/src/error/iter_result.md b/src/error/iter_result.md new file mode 100644 index 0000000000..66333ef853 --- /dev/null +++ b/src/error/iter_result.md @@ -0,0 +1,81 @@ +# `Iter>` + +A function you call on an iterable might fail, for example: +```rust,editable +fn main() { + let strings = vec!["tofu", "93", "18"]; + let possible_numbers: Vec> = strings + .into_iter() + .map(|s| s.parse()) + .collect(); + println!("Results: {:?}", possible_numbers); +} +``` + +Let's step through strategies for handling this. + +## Ignore the failed items with `filter_map()` + +`filter_map` calls a function and filters out the results that are `None`. + +```rust,editable +fn main() { + let strings = vec!["tofu", "93", "18"]; + let numbers: Vec = strings + .into_iter() + .map(|s| s.parse()) + .filter_map(Result::ok) + .collect(); + println!("Results: {:?}", numbers); +} +``` + +## Fail the entire operation with `collect()` + +`Result` implements `FromIter` so that a vector of results (Vec>) +can be turned into a result with a vector (Result, E>). Once an +`Result::Err` is found, the iteration will terminate. + +```rust,editable +fn main() { + let strings = vec!["tofu", "93", "18"]; + let numbers: Result, _> = strings + .into_iter() + .map(|s| s.parse()) + .collect(); + println!("Results: {:?}", numbers); +} +``` + +This same technique can be used with `Option` as well. + +## Collect all valid values and failures with `partition()` + +```rust,editable +fn main() { + let strings = vec!["tofu", "93", "18"]; + let (numbers, errors): (Vec>, Vec<_>) = strings + .into_iter() + .map(|s| s.parse()) + .partition(Result::is_ok); + println!("Numbers: {:?}", numbers); + println!("Errors: {:?}", errors); +} +``` + +When you look at the results, you'll note that everything is still wrapped in +`Result`. A little more boilerplate is needed for this. + +```rust,editable +fn main() { + let strings = vec!["tofu", "93", "18"]; + let (numbers, errors): (Vec>, Vec<_>) = strings + .into_iter() + .map(|s| s.parse()) + .partition(Result::is_ok); + let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect(); + let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect(); + println!("Numbers: {:?}", numbers); + println!("Errors: {:?}", errors); +} +``` From ce82b643a6865aa13712fc839185262cc1c49f63 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 15 Sep 2017 11:07:05 -0400 Subject: [PATCH 0660/1122] fix bullet list https://www.reddit.com/r/rust/comments/7041nk/rust_by_example_has_been_ported_to_mdbook_please/dn0shbg/ --- src/attribute.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/attribute.md b/src/attribute.md index 574d893221..3540b31ff1 100644 --- a/src/attribute.md +++ b/src/attribute.md @@ -4,6 +4,7 @@ An attribute is metadata applied to some module, crate or item. This metadata can be used to/for: + * [conditional compilation of code][cfg] * [set crate name, version and type (binary or library)][crate] * disable [lints][lint] (warnings) From 39eafd52cd5c23209df4cfc13f091e0785348da7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 15 Sep 2017 09:37:47 -0600 Subject: [PATCH 0661/1122] Improve wording in iter_result section --- src/error/iter_result.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/error/iter_result.md b/src/error/iter_result.md index 66333ef853..f7e415adaa 100644 --- a/src/error/iter_result.md +++ b/src/error/iter_result.md @@ -1,6 +1,7 @@ -# `Iter>` +# Iterating over `Result`s + +An `Iter::map` operation might fail, for example: -A function you call on an iterable might fail, for example: ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; @@ -32,8 +33,8 @@ fn main() { ## Fail the entire operation with `collect()` -`Result` implements `FromIter` so that a vector of results (Vec>) -can be turned into a result with a vector (Result, E>). Once an +`Result` implements `FromIter` so that a vector of results (`Vec>`) +can be turned into a result with a vector (`Result, E>`). Once an `Result::Err` is found, the iteration will terminate. ```rust,editable @@ -47,7 +48,7 @@ fn main() { } ``` -This same technique can be used with `Option` as well. +This same technique can be used with `Option`. ## Collect all valid values and failures with `partition()` From a34cd6b494b641191beab980a5ca23f078449e62 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 15 Sep 2017 10:29:23 -0600 Subject: [PATCH 0662/1122] Trying to simplify iter_result section. I'm concerned that the type signatures for the variables was a nasty collection of symbols, making it harder for new users to pick up on whats going on, so I'm instead experimenting with specifying the type for `parse`. --- src/error/iter_result.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/error/iter_result.md b/src/error/iter_result.md index f7e415adaa..822c9d3828 100644 --- a/src/error/iter_result.md +++ b/src/error/iter_result.md @@ -5,9 +5,9 @@ An `Iter::map` operation might fail, for example: ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let possible_numbers: Vec> = strings + let possible_numbers: Vec<_> = strings .into_iter() - .map(|s| s.parse()) + .map(|s| s.parse::()) .collect(); println!("Results: {:?}", possible_numbers); } @@ -22,9 +22,9 @@ Let's step through strategies for handling this. ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let numbers: Vec = strings + let numbers: Vec<_> = strings .into_iter() - .map(|s| s.parse()) + .map(|s| s.parse::()) .filter_map(Result::ok) .collect(); println!("Results: {:?}", numbers); @@ -40,9 +40,9 @@ can be turned into a result with a vector (`Result, E>`). Once an ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let numbers: Result, _> = strings + let numbers: Result, _> = strings .into_iter() - .map(|s| s.parse()) + .map(|s| s.parse::()) .collect(); println!("Results: {:?}", numbers); } @@ -55,9 +55,9 @@ This same technique can be used with `Option`. ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let (numbers, errors): (Vec>, Vec<_>) = strings + let (numbers, errors): (Vec<_>, Vec<_>) = strings .into_iter() - .map(|s| s.parse()) + .map(|s| s.parse::()) .partition(Result::is_ok); println!("Numbers: {:?}", numbers); println!("Errors: {:?}", errors); @@ -70,9 +70,9 @@ When you look at the results, you'll note that everything is still wrapped in ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let (numbers, errors): (Vec>, Vec<_>) = strings + let (numbers, errors): (Vec<_>, Vec<_>) = strings .into_iter() - .map(|s| s.parse()) + .map(|s| s.parse::()) .partition(Result::is_ok); let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect(); let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect(); From fa3cab9793de4361f42ef09989ff91d8082f438c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 15 Sep 2017 14:30:23 -0400 Subject: [PATCH 0663/1122] Fix title in summary --- src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d467a0bc10..d3b2f331b2 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -143,7 +143,7 @@ - [Defining an error type](error/define_error_type.md) - [Other uses of `try!`](error/reenter_try.md) - [`Box`ing errors](error/boxing_errors.md) - - [`Iter>`](error/iter_result.md) + - [Iterating over `Result`s](error/iter_result.md) - [Std library types](std.md) - [Box, stack and heap](std/box.md) From c59ca9ee35c15a829048b9ff9f96f12239e821e2 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 15 Sep 2017 14:36:42 -0400 Subject: [PATCH 0664/1122] add issue stuff to CONTRIBUTING.md --- CONTRIBUTING.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7afd6d7057..424fc4155e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,14 @@ You can find the issue tracker [on GitHub](https://github.com/rust-lang/rust-by-example/issues). If you've found a problem with RBE, please open an issue there. -Information about labels is coming soon! +We use the following labels: + +* `enhancement`: This is for any request for new sections or functionality. +* `bug`: This is for anything that's in RBE, but incorrect or not working. +* `discussion`: A discussion about improving something in RBE; this may lead to new + enhancement or bug issues. +* `E-mentor`: This issue has someone dedicated to helping a new contributor fix it! + Can apply to both enhancement or bug issues. ## Development workflow From 5a98e3bab964af8b372acb4a3ede487001cdc643 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 16 Sep 2017 16:00:10 +0200 Subject: [PATCH 0665/1122] Fix markdown link to https://rustbyexample.com/ --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 82805f2337..6ac81725b1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Learn Rust with examples (Live code editor included) ## Using If you'd like to read Rust by Example, you can visit -[https://rustbyexample.com/][] to read it online. +[https://rustbyexample.com/](https://rustbyexample.com/) to read it online. If you'd like to read it locally, [install Rust], and then: From e074d211b0a0714a9affce434513d4453c8fb8fe Mon Sep 17 00:00:00 2001 From: Norman Ritchie Date: Tue, 19 Sep 2017 12:57:26 +0300 Subject: [PATCH 0666/1122] Fix open subcommans --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 424fc4155e..414ef0edc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,7 +56,7 @@ To build RBE, [install Rust], and then: [install Rust]: http://rust-lang.org/install.html -The files will be in the `book` directory at the top-level; `mdbook open` will +The files will be in the `book` directory at the top-level; `mdbook serve` will open the contents in your web browser. To run the tests: diff --git a/README.md b/README.md index 6ac81725b1..8284257169 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ If you'd like to read it locally, [install Rust], and then: > cd rust-by-example > cargo install mdbook > mdbook build -> mdbook open +> mdbook serve ``` [install Rust]: http://rust-lang.org/install.html From 546ebf1da2b17c66b0801e293283789a2a283afb Mon Sep 17 00:00:00 2001 From: Aravindh Sridaran Date: Tue, 19 Sep 2017 13:50:53 +0200 Subject: [PATCH 0667/1122] Adding edit in github link to menubar --- theme/index.hbs | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 theme/index.hbs diff --git a/theme/index.hbs b/theme/index.hbs new file mode 100644 index 0000000000..8f819009f4 --- /dev/null +++ b/theme/index.hbs @@ -0,0 +1,171 @@ + + + + + {{ title }} + + + + + + + + + + + + + + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + + + + + + + + + + + + + {{#each additional_js}} + + {{/each}} + + + + + + + + + + + +
+ +
+ + +
+ {{{ content }}} +
+ + + {{#previous}} + + {{/previous}} + + {{#next}} + + {{/next}} + +
+ + {{#previous}} + + {{/previous}} + + {{#next}} + + {{/next}} + +
+ + + + + + + {{{livereload}}} + + {{#if google_analytics}} + + {{/if}} + + {{#if playpens_editable}} + + + + + + {{/if}} + + + + + \ No newline at end of file From d44e9a346b68c0888763d7cd7dee01f59762dcf0 Mon Sep 17 00:00:00 2001 From: Zengor Date: Tue, 19 Sep 2017 11:02:35 -0300 Subject: [PATCH 0668/1122] Switch from `try!` to `?` --- src/SUMMARY.md | 6 ++--- src/error/boxing_errors.md | 4 ++-- .../multiple_error_types/early_returns.md | 2 +- .../{enter_try.md => enter_question_mark.md} | 18 +++++++------- ...eenter_try.md => reenter_question_mark.md} | 24 +++++++++---------- .../print/print_display/testcase_list.md | 17 ++++++------- src/std/result/{try.md => question_mark.md} | 15 ++++++------ src/std_misc/fs.md | 4 ++-- 8 files changed, 46 insertions(+), 44 deletions(-) rename src/error/multiple_error_types/{enter_try.md => enter_question_mark.md} (81%) rename src/error/{reenter_try.md => reenter_question_mark.md} (80%) rename src/std/result/{try.md => question_mark.md} (83%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c6e1bf8f63..3ea70900e9 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -139,9 +139,9 @@ - [aliases for `Result`](error/result/result_alias.md) - [Multiple error types](error/multiple_error_types.md) - [Early returns](error/multiple_error_types/early_returns.md) - - [Introducing `try!`](error/multiple_error_types/enter_try.md) + - [Introducing `?`](error/multiple_error_types/enter_question_mark.md) - [Defining an error type](error/define_error_type.md) - - [Other uses of `try!`](error/reenter_try.md) + - [Other uses of `?`](error/reenter_question_mark.md) - [`Box`ing errors](error/boxing_errors.md) - [Iterating over `Result`s](error/iter_result.md) @@ -151,7 +151,7 @@ - [Strings](std/str.md) - [`Option`](std/option.md) - [`Result`](std/result.md) - - [`try!`](std/result/try.md) + - [`?`](std/result/question_mark.md) - [`panic!`](std/panic.md) - [HashMap](std/hash.md) - [Alternate/custom key types](std/hash/alt_key_types.md) diff --git a/src/error/boxing_errors.md b/src/error/boxing_errors.md index 48a0b5bf51..7c31bb5af7 100644 --- a/src/error/boxing_errors.md +++ b/src/error/boxing_errors.md @@ -89,8 +89,8 @@ impl error::Error for DoubleError { } fn double_first(vec: Vec<&str>) -> Result { - let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); - let parsed = try!(first.parse::()); + let first = vec.first().ok_or(DoubleError::EmptyVec)?; + let parsed = first.parse::()?; Ok(2 * parsed) } diff --git a/src/error/multiple_error_types/early_returns.md b/src/error/multiple_error_types/early_returns.md index 6030246e2c..0e70f1d5e5 100644 --- a/src/error/multiple_error_types/early_returns.md +++ b/src/error/multiple_error_types/early_returns.md @@ -48,5 +48,5 @@ At this point, we've learned to explicitly handle errors using combinators and early returns. While we generally want to avoid panicking, explicitly handling all of our errors is cumbersome. -In the next section, we'll introduce `try!` for the cases where we simply +In the next section, we'll introduce `?` for the cases where we simply need to `unwrap` without possibly inducing `panic`. diff --git a/src/error/multiple_error_types/enter_try.md b/src/error/multiple_error_types/enter_question_mark.md similarity index 81% rename from src/error/multiple_error_types/enter_try.md rename to src/error/multiple_error_types/enter_question_mark.md index 666f14d62f..c3de9e1c70 100644 --- a/src/error/multiple_error_types/enter_try.md +++ b/src/error/multiple_error_types/enter_question_mark.md @@ -1,15 +1,15 @@ -# Introducing `try!` +# Introducing `?` Sometimes we just want the simplicity of `unwrap` without the possibility of a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when -what we really wanted was to get the variable *out*. This is exactly the purpose of `try!`. +what we really wanted was to get the variable *out*. This is exactly the purpose of `?`. Upon finding an `Err`, there are two valid actions to take: 1. `panic!` which we already decided to try to avoid if possible 2. `return` because an `Err` means it cannot be handled -`try!` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s +`?` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s instead of `panic`s on `Err`s. Let's see how we can simplify the earlier example that used combinators: @@ -18,11 +18,11 @@ example that used combinators: type Result = std::result::Result; fn double_first(vec: Vec<&str>) -> Result { - let first = try!(vec.first() - .ok_or("Please use a vector with at least one element.".to_owned())); + let first = vec.first() + .ok_or("Please use a vector with at least one element.".to_owned())?; - let value = try!(first.parse::() - .map_err(|e| e.to_string())); + let value = first.parse::() + .map_err(|e| e.to_string())?; Ok(2 * value) } @@ -47,7 +47,7 @@ Note that up until now, we've been using `String`s as errors. However, they are somewhat limiting as an error type. In the next section, we'll learn how to make more structured and informative errors by defining their types. -[^1]: See [re-enter try!][re_enter_try] for more details. +[^1]: See [re-enter ?][re_enter_try] for more details. ### See also: @@ -55,4 +55,4 @@ to make more structured and informative errors by defining their types. [result]: https://doc.rust-lang.org/std/result/enum.Result.html [io_result]: https://doc.rust-lang.org/std/io/type.Result.html -[re_enter_try]: /error/reenter_try.html +[re_enter_?]: /error/reenter_question_mark.html diff --git a/src/error/reenter_try.md b/src/error/reenter_question_mark.md similarity index 80% rename from src/error/reenter_try.md rename to src/error/reenter_question_mark.md index cb6ae1cd31..76ccfcb036 100644 --- a/src/error/reenter_try.md +++ b/src/error/reenter_question_mark.md @@ -1,4 +1,4 @@ -# Other uses of `try!` +# Other uses of `?` Notice in the previous example that our immediate reaction to calling `parse` is to `map` the error from a library error into our new custom @@ -11,15 +11,15 @@ error type: Since this is a simple and common operation, it would be convenient if it could be elided. Alas, because `and_then` is not sufficiently flexible, it -cannot. However, we can instead use `try!`. +cannot. However, we can instead use `?`. -`try!` was previously explained as either `unwrap` or `return Err(err)`. +`?` was previously explained as either `unwrap` or `return Err(err)`. This is only mostly true. It actually means `unwrap` or `return Err(From::from(err))`. Since `From::from` is a conversion utility -between different types, this means that if you `try!` where the error is +between different types, this means that if you `?` where the error is convertible to the return type, it will convert automatically. -Here, we rewrite the previous example using `try!`. As a result, the +Here, we rewrite the previous example using `?`. As a result, the `map_err` will go away when `From::from` is implemented for our error type: ```rust,editable @@ -35,7 +35,7 @@ enum DoubleError { } // Implement the conversion from `ParseIntError` to `DoubleError`. -// This will be automatically called by `try!` if a `ParseIntError` +// This will be automatically called by `?` if a `ParseIntError` // needs to be converted into a `DoubleError`. impl From for DoubleError { fn from(err: ParseIntError) -> DoubleError { @@ -54,11 +54,11 @@ impl fmt::Display for DoubleError { } // The same structure as before but rather than chain all `Results` -// and `Options` along, we `try!` to get the inner value out immediately. +// and `Options` along, we `?` to get the inner value out immediately. fn double_first(vec: Vec<&str>) -> Result { // Still convert to `Result` by stating how to convert `None`. - let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); - let parsed = try!(first.parse::()); + let first = vec.first().ok_or(DoubleError::EmptyVec)?; + let parsed = first.parse::()?; Ok(2 * parsed) } @@ -82,7 +82,7 @@ fn main() { ``` This is actually fairly clean now. Compared with the original `panic`, it -is very similar to replacing the `unwrap` calls with `try!` except that the +is very similar to replacing the `unwrap` calls with `?` except that the return types are `Result`. As a result, they must be destructured at the top level. @@ -101,7 +101,7 @@ eventually need to meet higher expectations of error handling implementation. ### See also: -[`From::from`][from] and [`try!`][try] +[`From::from`][from] and [`?`][q_mark] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[try]: https://doc.rust-lang.org/std/macro.try!.html +[q_mark]: https://doc.rust-lang.org/reference/expressions.html#the--operator diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index 8246384b49..d40389c2c1 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -3,21 +3,22 @@ Implementing `fmt::Display` for a structure where the elements must each be handled sequentially is tricky. The problem is that each `write!` generates a `fmt::Result`. Proper handling of this requires dealing with *all* the -results. Rust provides the `try!` macro and alternatively the equivalent -`?` operator for exactly this purpose. +results. Rust provides the `?` operator for exactly this purpose. -Using `try!` on `write!` looks like this: +Using `?` on `write!` looks like this: ```rust,ignore // Try `write!` to see if it errors. If it errors, return // the error. Otherwise continue. -try!(write!(f, "{}", value)); +write!(f, "{}", value)?; ``` -The `?` shorthand alternative looks like this: +Alternatively, you can also use the `try!` macro, which works the same way. +This is a bit more verbose and no longer recommended, but you may still see it in +older Rust code. Using `try` looks like this: ```rust,ignore -write!(f, "{}", value)?; +try!(write!(f, "{}", value)); ``` With `?` available, implementing `fmt::Display` for a `Vec` is @@ -68,11 +69,11 @@ Try changing the program so that the index of each element in the vector is also ### See also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], -[`try!`][try], and [`vec!`][vec] +[`?`][q_mark], and [`vec!`][vec] [for]: /flow_control/for.html [result]: /std/result.html [ref]: /scope/borrow/ref.html [struct]: /custom_types/structs.html -[try]: /std/result/try.html +[q_mark]: /std/result/question_mark.html [vec]: /std/vec.html diff --git a/src/std/result/try.md b/src/std/result/question_mark.md similarity index 83% rename from src/std/result/try.md rename to src/std/result/question_mark.md index 6349387519..4650702722 100644 --- a/src/std/result/try.md +++ b/src/std/result/question_mark.md @@ -1,9 +1,10 @@ -# `try!` +# `?` -Chaining results using match can get pretty untidy; luckily, the `try!` macro -can be used to make things pretty again. The `try!` macro expands to a match -expression, where the `Err(err)` branch expands to an early `return Err(err)`, -and the `Ok(ok)` branch expands to an `ok` expression. +Chaining results using match can get pretty untidy; luckily, the `?` operator +can be used to make things pretty again. `?` is used at the end of an expression +returning a `Result`, and is equivalent to a match expression, where the +`Err(err)` branch expands to an early `return Err(err)`, and the `Ok(ok)` branch +expands to an `ok` expression. ```rust,editable,ignore,mdbook-runnable mod checked { @@ -43,10 +44,10 @@ mod checked { // Intermediate function fn op_(x: f64, y: f64) -> MathResult { // if `div` "fails", then `DivisionByZero` will be `return`ed - let ratio = try!(div(x, y)); + let ratio = div(x, y)?; // if `ln` "fails", then `NegativeLogarithm` will be `return`ed - let ln = try!(ln(ratio)); + let ln = ln(ratio)?; sqrt(ln) } diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index 2f06c3e226..f6444cd231 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -13,7 +13,7 @@ use std::path::Path; // A simple implementation of `% cat path` fn cat(path: &Path) -> io::Result { - let mut f = try!(File::open(path)); + let mut f = File::open(path)?; let mut s = String::new(); match f.read_to_string(&mut s) { Ok(_) => Ok(s), @@ -23,7 +23,7 @@ fn cat(path: &Path) -> io::Result { // A simple implementation of `% echo s > path` fn echo(s: &str, path: &Path) -> io::Result<()> { - let mut f = try!(File::create(path)); + let mut f = File::create(path)?; f.write_all(s.as_bytes()) } From 5638d8b4f1df23c5843e8438fbe00b896ab04639 Mon Sep 17 00:00:00 2001 From: Zengor Date: Tue, 19 Sep 2017 11:09:01 -0300 Subject: [PATCH 0669/1122] Add a small section explaining `try` to "Enter `?`" --- .../enter_question_mark.md | 23 ++++++++++++++++++- .../print/print_display/testcase_list.md | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/error/multiple_error_types/enter_question_mark.md b/src/error/multiple_error_types/enter_question_mark.md index c3de9e1c70..df6f9dbaf6 100644 --- a/src/error/multiple_error_types/enter_question_mark.md +++ b/src/error/multiple_error_types/enter_question_mark.md @@ -47,7 +47,28 @@ Note that up until now, we've been using `String`s as errors. However, they are somewhat limiting as an error type. In the next section, we'll learn how to make more structured and informative errors by defining their types. -[^1]: See [re-enter ?][re_enter_try] for more details. + +## The `try!` macro + +Before there was `?`, the same functionality was achieved with the `try!` macro. +The `?` operator is now recommended, but you may still find `try!` when looking +at older code. The same `double_first` function from the previous example +would look like this using `try!`: + +```rust,ignore +fn double_first(vec: Vec<&str>) -> Result { + let first = try!(vec.first() + .ok_or("Please use a vector with at least one element.".to_owned())); + + let value = try!(first.parse::() + .map_err(|e| e.to_string())); + + Ok(2 * value) +} +``` + + +[^1]: See [re-enter ?][re_enter_?] for more details. ### See also: diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index d40389c2c1..ee332d0f2c 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -15,7 +15,7 @@ write!(f, "{}", value)?; Alternatively, you can also use the `try!` macro, which works the same way. This is a bit more verbose and no longer recommended, but you may still see it in -older Rust code. Using `try` looks like this: +older Rust code. Using `try!` looks like this: ```rust,ignore try!(write!(f, "{}", value)); From c0ad1bbbf254c7ffe28b7d9fa068327cff016fe2 Mon Sep 17 00:00:00 2001 From: Devin Brite Date: Tue, 19 Sep 2017 11:36:29 -0400 Subject: [PATCH 0670/1122] Fix "See Also" markdown on traits/ops --- src/trait/ops.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/ops.md b/src/trait/ops.md index 8d7ff3f97d..6de80d8e50 100644 --- a/src/trait/ops.md +++ b/src/trait/ops.md @@ -52,7 +52,7 @@ fn main() { } ``` -###See Also +### See Also [Add][add], [Syntax Index][syntax] From a1c5f8ca70be5ee46acd15bde9331729bbedaa66 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 19 Sep 2017 19:23:33 -0600 Subject: [PATCH 0671/1122] Consolidate general Result sections --- src/SUMMARY.md | 4 ++-- src/error/{multiple_error_types => result}/early_returns.md | 0 .../{multiple_error_types => result}/enter_question_mark.md | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/error/{multiple_error_types => result}/early_returns.md (100%) rename src/error/{multiple_error_types => result}/enter_question_mark.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3ea70900e9..1f59299861 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -137,9 +137,9 @@ - [`Result`](error/result.md) - [`map` for `Result`](error/result/result_map.md) - [aliases for `Result`](error/result/result_alias.md) + - [Early returns](error/result/early_returns.md) + - [Introducing `?`](error/result/enter_question_mark.md) - [Multiple error types](error/multiple_error_types.md) - - [Early returns](error/multiple_error_types/early_returns.md) - - [Introducing `?`](error/multiple_error_types/enter_question_mark.md) - [Defining an error type](error/define_error_type.md) - [Other uses of `?`](error/reenter_question_mark.md) - [`Box`ing errors](error/boxing_errors.md) diff --git a/src/error/multiple_error_types/early_returns.md b/src/error/result/early_returns.md similarity index 100% rename from src/error/multiple_error_types/early_returns.md rename to src/error/result/early_returns.md diff --git a/src/error/multiple_error_types/enter_question_mark.md b/src/error/result/enter_question_mark.md similarity index 100% rename from src/error/multiple_error_types/enter_question_mark.md rename to src/error/result/enter_question_mark.md From 247863ae606fedbeadd4363f772f8ee9dc3cad64 Mon Sep 17 00:00:00 2001 From: Aravindh Sridaran Date: Wed, 20 Sep 2017 10:28:44 +0200 Subject: [PATCH 0672/1122] Updated to use latest index.hbs from mdbook --- theme/index.hbs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/theme/index.hbs b/theme/index.hbs index 8f819009f4..d0bce85ba6 100644 --- a/theme/index.hbs +++ b/theme/index.hbs @@ -82,16 +82,18 @@ @@ -134,12 +136,11 @@ if ($(".fa").css("font-family") !== "FontAwesome") { $('').prependTo('head'); } - - // START - Rust Cookbook customization + // START - Rust-By-Example customization $("#edit-button").click(function(){ - var editWindow = window.open("https://github.com/rust-lang/rust-by-example/edit/master/src/{{ path }}"); - }); - // END - Rust Cookbook customization + var editWindow = window.open("https://github.com/rust-lang/rust-by-example/edit/master/src/{{ path }}"); + }); + // END - Rust-By-Example customization @@ -165,6 +166,14 @@ {{/if}} + {{#if is_print}} + + {{/if}} + From 1a6c76c8774c303abf56f74e76187e2561668349 Mon Sep 17 00:00:00 2001 From: Vishal Sodani Date: Wed, 20 Sep 2017 15:16:25 +0530 Subject: [PATCH 0673/1122] Add an example to demonstrate long tuple cannot be printed --- src/primitives/tuples.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index 3d6835ed7c..a471467348 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -31,9 +31,14 @@ fn main() { // Tuples can be tuple members let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); - + // Tuples are printable println!("tuple of tuples: {:?}", tuple_of_tuples); + + // But long Tuples cannot be printed + // let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + // println!("too long tuple: {:?}", too_long_tuple); + // TODO ^ Uncomment the above 2 lines to see the compiler error let pair = (1, true); println!("pair is {:?}", pair); From 41d24947b0342ebe3803898f2675d590cb2d9aad Mon Sep 17 00:00:00 2001 From: Vishal Sodani Date: Thu, 21 Sep 2017 06:55:41 +0530 Subject: [PATCH 0674/1122] Fix whitespace --- src/primitives/tuples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index a471467348..1a9095d26a 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -31,7 +31,7 @@ fn main() { // Tuples can be tuple members let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); - + // Tuples are printable println!("tuple of tuples: {:?}", tuple_of_tuples); From a1308c77ab3e871220bf7dadf88af2411a3a7727 Mon Sep 17 00:00:00 2001 From: Alexey Zabelin Date: Wed, 20 Sep 2017 22:36:55 -0400 Subject: [PATCH 0675/1122] Fix a small typo --- src/hello/print/print_debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index b157596fed..da22677a71 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -22,7 +22,7 @@ struct DebugPrintable(i32); All `std` library types automatically are printable with `{:?}` too: -```rust,editible +```rust,editable // Derive the `fmt::Debug` implementation for `Structure`. `Structure` // is a structure which contains a single `i32`. #[derive(Debug)] From 84fc11a08bbd13dc9b6f13318e10bab7eca9f693 Mon Sep 17 00:00:00 2001 From: Zengor Date: Wed, 20 Sep 2017 23:53:05 -0300 Subject: [PATCH 0676/1122] Fix small typo in Vec chapter --- src/std/vec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/vec.md b/src/std/vec.md index 40784b26b2..07408fe5b9 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -42,7 +42,7 @@ fn main() { // `Vector`s can be easily iterated over println!("Contents of xs:"); for x in xs.iter() { - println!("> {}"x); + println!("> {}", x); } // A `Vector` can also be iterated over while the iteration From 44fb54cb6dc3d4e780f9c03acbef711c46281641 Mon Sep 17 00:00:00 2001 From: Lucas Morales Date: Thu, 21 Sep 2017 21:00:18 -0400 Subject: [PATCH 0677/1122] improve enum example --- src/custom_types/enum.md | 64 +++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index e5a6b5a0da..c48daba01b 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -8,52 +8,50 @@ an `enum`. // An attribute to hide warnings for unused code. #![allow(dead_code)] -// Create an `enum` to classify someone. Note how both names -// and type information together specify the variant: -// `Engineer != Scientist` and `Height(i32) != Weight(i32)`. Each -// is different and independent. -enum Person { +// Create an `enum` to classify a web event. Note how both +// names and type information together specify the variant: +// `PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`. +// Each is different and independent. +enum WebEvent { // An `enum` may either be `unit-like`, - Engineer, - Scientist, + PageLoad, + PageUnload, // like tuple structs, - Height(i32), - Weight(i32), + KeyPress(char), + Paste(String), // or like structures. - Info { name: String, height: i32 } + Click { x: i64, y: i64 }, } -// A function which takes a `Person` enum as an argument and +// A function which takes a `WebEvent` enum as an argument and // returns nothing. -fn inspect(p: Person) { - // Usage of an `enum` must cover all cases (irrefutable) - // so a `match` is used to branch over it. - match p { - Person::Engineer => println!("Is an engineer!"), - Person::Scientist => println!("Is a scientist!"), - // Destructure `i` from inside the `enum`. - Person::Height(i) => println!("Has a height of {}.", i), - Person::Weight(i) => println!("Has a weight of {}.", i), - // Destructure `Info` into `name` and `height`. - Person::Info { name, height } => { - println!("{} is {} tall!", name, height); +fn inspect(event: WebEvent) { + match event { + WebEvent::PageLoad => println!("page loaded"), + WebEvent::PageUnload => println!("page unloaded"), + // Destructure `c` from inside the `enum`. + WebEvent::KeyPress(c) => println!("pressed '{}'.", c), + WebEvent::Paste(s) => println!("pasted \"{}\".", s), + // Destructure `Click` into `x` and `y`. + WebEvent::Click { x, y } => { + println!("clicked at x={}, y={}.", x, y); }, } } fn main() { - let person = Person::Height(18); - let amira = Person::Weight(10); + let pressed = WebEvent::KeyPress('x'); // `to_owned()` creates an owned `String` from a string slice. - let dave = Person::Info { name: "Dave".to_owned(), height: 72 }; - let rebecca = Person::Scientist; - let rohan = Person::Engineer; + let pasted = WebEvent::Paste("my text".to_owned()); + let click = WebEvent::Click { x: 20, y: 80 }; + let load = WebEvent::PageLoad; + let unload = WebEvent::PageUnload; - inspect(person); - inspect(amira); - inspect(dave); - inspect(rebecca); - inspect(rohan); + inspect(pressed); + inspect(pasted); + inspect(click); + inspect(load); + inspect(unload); } ``` From 3eb4e7350e06f5c22cf4f6593f961af4c36d59d7 Mon Sep 17 00:00:00 2001 From: Devin Brite Date: Thu, 21 Sep 2017 23:42:26 -0400 Subject: [PATCH 0678/1122] Improve primitives section Fix/Improve: #783, #832 - Distinguish scalar and compound types - Add an example of inference - Improve example of mutability - Add an example of shadowing - Add `mut` to "see also:" - Add shadowing to "see also:" - Add inference to "see also:" --- src/primitives.md | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/primitives.md b/src/primitives.md index b7e01cb85f..6b84c6cb2c 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -2,18 +2,25 @@ Rust provides access to a wide variety of `primitives`. A sample includes: + +### Scalar Types + * signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) * unsigned integers: `u8`, `u16`, `u32`, `u64` and `usize` (pointer size) * floating point: `f32`, `f64` * `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) * `bool` either `true` or `false` -* and the unit type `()`, whose only value is also `()` + + +### Compound Types + * arrays like `[1, 2, 3]` * tuples like `(1, true)` +* and the unit type `()`, whose only value is also `()` Variables can always be *type annotated*. Numbers may additionally be annotated via a *suffix* or *by default*. Integers default to `i32` and -floats to `f64`. +floats to `f64`. Note that Rust can also infer types from context. ```rust,editable,ignore,mdbook-runnable fn main() { @@ -26,16 +33,28 @@ fn main() { // Or a default will be used. let default_float = 3.0; // `f64` let default_integer = 7; // `i32` - - let mut mutable = 12; // Mutable `i32`. - - // Error! The type of a variable can't be changed + + // A type can also be inferred from context + let mut inferred_type = 12; // Type i64 is inferred from another line + inferred_type = 4294967296i64; + + // A mutable variable's value can be changed. + let mut mutable = 12; // Mutable `i32` + mutable = 21; + + // Error! The type of a variable can't be changed. mutable = true; + + // Variables can be overwritten with shadowing. + let mutable = true; } ``` ### See also: -[the `std` library][std] +[the `std` library][std], [`mut`][mut], [inference], and [shadowing] [std]: https://doc.rust-lang.org/std/ +[mut]: https://rustbyexample.com/variable_bindings/mut.html +[inference]: https://rustbyexample.com/cast/inference.html +[shadowing]: https://rustbyexample.com/variable_bindings/scope.html From ef221515b01e46a95207529523404c69b7e74d8c Mon Sep 17 00:00:00 2001 From: Devin Brite Date: Fri, 22 Sep 2017 15:34:34 -0400 Subject: [PATCH 0679/1122] Move unit type `()` back to scalars --- src/primitives.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/primitives.md b/src/primitives.md index 6b84c6cb2c..36561fd78a 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -10,13 +10,15 @@ Rust provides access to a wide variety of `primitives`. A sample includes: * floating point: `f32`, `f64` * `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) * `bool` either `true` or `false` +* and the unit type `()`, whose only possible value is an empty tuple: `()` +Despite the value of a unit type being a tuple, it is not considered a +compound type because it does not contain multiple values. ### Compound Types * arrays like `[1, 2, 3]` * tuples like `(1, true)` -* and the unit type `()`, whose only value is also `()` Variables can always be *type annotated*. Numbers may additionally be annotated via a *suffix* or *by default*. Integers default to `i32` and From c58a286b119c16c423791f7688ed8b432e9cda3c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 20 Sep 2017 20:33:20 -0600 Subject: [PATCH 0680/1122] Update Result examples for new flow Example changes focused on - Handling the need of `?`, so the same example could be used in this section. - Avoid `Result<_, String>` so that someone picking up in the middle to handle a specific need they have won't pick up on the approaches taken for pedalogical reasons when better choices are explained later. Links and examples have been tested. --- src/error/result.md | 28 +++++---- src/error/result/early_returns.md | 56 ++++++++--------- src/error/result/enter_question_mark.md | 81 +++++++++++-------------- src/error/result/result_alias.md | 24 ++++---- src/error/result/result_map.md | 66 ++++++++++++++------ 5 files changed, 139 insertions(+), 116 deletions(-) diff --git a/src/error/result.md b/src/error/result.md index be10b8ad96..760003b924 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -1,6 +1,6 @@ # `Result` -[`Result`][result] is a richer version of the [`Option`][option] type that +[`Result`][result] is a richer version of the [`Option`][option] type that describes possible *error* instead of possible *absence*. That is, `Result` could have one of two outcomes: @@ -10,37 +10,39 @@ That is, `Result` could have one of two outcomes: By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`. -Like `Option`, `Result` has many methods associated with it. `unwrap()`, for -example, either yields the element `T` or `panic`s. For case handling, +Like `Option`, `Result` has many methods associated with it. `unwrap()`, for +example, either yields the element `T` or `panic`s. For case handling, there are many combinators between `Result` and `Option` that overlap. -In working with Rust, you will likely encounter methods that return the -`Result` type, such as the [`parse()`][parse] method. It might not always -be possible to parse a string into the other type, so `parse()` returns a +In working with Rust, you will likely encounter methods that return the +`Result` type, such as the [`parse()`][parse] method. It might not always +be possible to parse a string into the other type, so `parse()` returns a `Result` indicating possible failure. Let's see what happens when we successfully and unsuccessfully `parse()` a string: ```rust,editable,ignore,mdbook-runnable -fn double_number(number_str: &str) -> i32 { +fn multiply(first_number_str: &str, second_number_str: &str) -> i32 { // Let's try using `unwrap()` to get the number out. Will it bite us? - 2 * number_str.parse::().unwrap() + let first_number = first_number_str.parse::().unwrap(); + let second_number = second_number_str.parse::().unwrap(); + first_number * second_number } fn main() { - let twenty = double_number("10"); + let twenty = multiply("10", "2"); println!("double is {}", twenty); - let tt = double_number("t"); + let tt = multiply("t", "2"); println!("double is {}", tt); } ``` -In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` -to `panic` on. Additionally, the `panic` exits our program and provides an +In the unsuccessful case, `parse()` leaves us with an error for `unwrap()` +to `panic` on. Additionally, the `panic` exits our program and provides an unpleasant error message. -To improve the quality of our error message, we should be more specific +To improve the quality of our error message, we should be more specific about the return type and consider explicitly handling the error. [option]: https://doc.rust-lang.org/std/option/enum.Option.html diff --git a/src/error/result/early_returns.md b/src/error/result/early_returns.md index 0e70f1d5e5..e76615131f 100644 --- a/src/error/result/early_returns.md +++ b/src/error/result/early_returns.md @@ -1,52 +1,46 @@ # Early returns -In the previous example, we explicitly handled the errors using combinators. -Another way to deal with this case analysis is to use a combination of -`match` statements and *early returns*. +In the previous example, we explicitly handled the errors using combinators. +Another way to deal with this case analysis is to use a combination of +`match` statements and *early returns*. -That is, we can simply stop executing the function and return the error if -one occurs. For some, this form of code can be easier to both read and +That is, we can simply stop executing the function and return the error if +one occurs. For some, this form of code can be easier to both read and write. Consider this version of the previous example, rewritten using early returns: ```rust,editable -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - let first = match vec.first() { - Some(first) => first, - None => return Err("Please use a vector with at least one element.".to_owned()) +use std::num::ParseIntError; + +fn multiply(first_number_str: &str, second_number_str: &str) -> Result { + let first_number = match first_number_str.parse::() { + Ok(first_number) => first_number, + Err(e) => return Err(e), }; - // Double the number inside if `parse` works fine. - // Otherwise, map any errors that `parse` yields to `String`. - match first.parse::() { - Ok(i) => Ok(2 * i), - Err(e) => Err(e.to_string()), - } + let second_number = match second_number_str.parse::() { + Ok(second_number) => second_number, + Err(e) => return Err(e), + }; + + Ok(first_number * second_number) } -fn print(result: Result) { +fn print(result: Result) { match result { - Ok(n) => println!("The first doubled is {}", n), + Ok(n) => println!("n is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); + print(multiply("10", "2")); + print(multiply("t", "2")); } ``` -At this point, we've learned to explicitly handle errors using combinators -and early returns. While we generally want to avoid panicking, explicitly +At this point, we've learned to explicitly handle errors using combinators +and early returns. While we generally want to avoid panicking, explicitly handling all of our errors is cumbersome. -In the next section, we'll introduce `?` for the cases where we simply -need to `unwrap` without possibly inducing `panic`. +In the next section, we'll introduce `?` for the cases where we simply +need to `unwrap` without possibly inducing `panic`. diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index df6f9dbaf6..265aa38204 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -1,79 +1,72 @@ # Introducing `?` -Sometimes we just want the simplicity of `unwrap` without the possibility of -a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when -what we really wanted was to get the variable *out*. This is exactly the purpose of `?`. +Sometimes we just want the simplicity of `unwrap` without the possibility of +a `panic`. Until now, `unwrap` has forced us to nest deeper and deeper when +what we really wanted was to get the variable *out*. This is exactly the purpose of `?`. Upon finding an `Err`, there are two valid actions to take: 1. `panic!` which we already decided to try to avoid if possible 2. `return` because an `Err` means it cannot be handled -`?` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s -instead of `panic`s on `Err`s. Let's see how we can simplify the earlier +`?` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s +instead of `panic`s on `Err`s. Let's see how we can simplify the earlier example that used combinators: ```rust,editable -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - let first = vec.first() - .ok_or("Please use a vector with at least one element.".to_owned())?; - - let value = first.parse::() - .map_err(|e| e.to_string())?; - - Ok(2 * value) +use std::num::ParseIntError; + +fn multiply(first_number_str: &str, second_number_str: &str) -> Result { + let first_number = first_number_str.parse::()?; + let second_number = second_number_str.parse::()?; + + Ok(first_number * second_number) } -fn print(result: Result) { +fn print(result: Result) { match result { - Ok(n) => println!("The first doubled is {}", n), + Ok(n) => println!("n is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); + print(multiply("10", "2")); + print(multiply("t", "2")); } ``` -Note that up until now, we've been using `String`s as errors. However, they -are somewhat limiting as an error type. In the next section, we'll learn how -to make more structured and informative errors by defining their types. - - ## The `try!` macro Before there was `?`, the same functionality was achieved with the `try!` macro. The `?` operator is now recommended, but you may still find `try!` when looking -at older code. The same `double_first` function from the previous example +at older code. The same `multiply` function from the previous example would look like this using `try!`: -```rust,ignore -fn double_first(vec: Vec<&str>) -> Result { - let first = try!(vec.first() - .ok_or("Please use a vector with at least one element.".to_owned())); - - let value = try!(first.parse::() - .map_err(|e| e.to_string())); - - Ok(2 * value) +```rust,editable +use std::num::ParseIntError; + +fn multiply(first_number_str: &str, second_number_str: &str) -> Result { + let first_number = try!(first_number_str.parse::()); + let second_number = try!(second_number_str.parse::()); + + Ok(first_number * second_number) } -``` +fn print(result: Result) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} -[^1]: See [re-enter ?][re_enter_?] for more details. +fn main() { + print(multiply("10", "2")); + print(multiply("t", "2")); +} +``` -### See also: -[`Result`][result] and [`io::Result`][io_result] +[^1]: See [re-enter ?][re_enter_?] for more details. -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: https://doc.rust-lang.org/std/io/type.Result.html [re_enter_?]: /error/reenter_question_mark.html diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md index 2727ca0c85..50a38eaf52 100644 --- a/src/error/result/result_alias.md +++ b/src/error/result/result_alias.md @@ -1,12 +1,13 @@ # aliases for `Result` -How about when we want to reuse a specific `Result` type many times? -Recall that Rust allows us to create [aliases][typealias]. Conveniently, +How about when we want to reuse a specific `Result` type many times? +Recall that Rust allows us to create [aliases][typealias]. Conveniently, we can define one for the specific `Result` in question. -At a module level, creating aliases can be particularly helpful. Errors -found in a specific module often have the same `Err` type, so a single alias -can succinctly define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! +At a module level, creating aliases can be particularly helpful. Errors +found in a specific module often have the same `Err` type, so a single alias +can succinctly define *all* associated `Results`. This is so useful that the +`std` library even supplies one: [`io::Result`][io_result]! Here's a quick example to show off the syntax: @@ -17,8 +18,10 @@ use std::num::ParseIntError; type AliasedResult = Result; // Use the above alias to refer to our specific `Result` type. -fn double_number(number_str: &str) -> AliasedResult { - number_str.parse::().map(|n| 2 * n) +fn multiply(first_number_str: &str, second_number_str: &str) -> AliasedResult { + first_number_str.parse::().and_then(|first_number| { + second_number_str.parse::().map(|second_number| first_number * second_number) + }) } // Here, the alias again allows us to save some space. @@ -30,15 +33,14 @@ fn print(result: AliasedResult) { } fn main() { - print(double_number("10")); - print(double_number("t")); + print(multiply("10", "2")); + print(multiply("t", "2")); } ``` ### See also: -[`Result`][result] and [`io::Result`][io_result] +[`io::Result`][io_result] [typealias]: /cast/alias.html -[result]: https://doc.rust-lang.org/std/result/enum.Result.html [io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/src/error/result/result_map.md b/src/error/result/result_map.md index 3d21543d83..5bc72fbe67 100644 --- a/src/error/result/result_map.md +++ b/src/error/result/result_map.md @@ -1,34 +1,66 @@ # `map` for `Result` -Panicking in the previous example gave us an unhelpful error message. -To avoid that, we need to be more specific about the return type. There, the -regular element is of type `i32`. +Panicking in the previous example's `multiply` does not make for robust code. +Generally, we want to return the error to the caller so it can decide what is +the right way to respond to errors. -To determine the `Err` type, we look to -[`parse()`][parse], which is implemented with the [`FromStr`][from_str] trait for -[`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. +We first need to know what kind of error type we are dealing with. To determine +the `Err` type, we look to [`parse()`][parse], which is implemented with the +[`FromStr`][from_str] trait for [`i32`][i32]. As a result, the `Err` type is +specified as [`ParseIntError`][parse_int_error]. -In the example below, the straightforward `match` statement leads to code -that is overall more cumbersome. Luckily, the `map` method of `Option` is -one of many combinators also implemented for `Result`. [`enum.Result`][result] -contains a complete listing. +In the example below, the straightforward `match` statement leads to code +that is overall more cumbersome. ```rust,editable use std::num::ParseIntError; // With the return type rewritten, we use pattern matching without `unwrap()`. -fn double_number(number_str: &str) -> Result { - match number_str.parse::() { - Ok(n) => Ok(2 * n), +fn multiply(first_number_str: &str, second_number_str: &str) -> Result { + match first_number_str.parse::() { + Ok(first_number) => { + match second_number_str.parse::() { + Ok(second_number) => { + Ok(first_number * second_number) + }, + Err(e) => Err(e), + } + }, Err(e) => Err(e), } } +fn print(result: Result) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + // This still presents a reasonable answer. + let twenty = multiply("10", "2"); + print(twenty); + + // The following now provides a much more helpful error message. + let tt = multiply("t", "2"); + print(tt); +} +``` + +Luckily, `Option`'s `map`, `and_then`, and many other combinators are also +implemented for `Result`. [`enum.Result`][result] contains a complete listing. + +```rust,editable +use std::num::ParseIntError; + // As with `Option`, we can use combinators such as `map()`. // This function is otherwise identical to the one above and reads: // Modify n if the value is valid, otherwise pass on the error. -fn double_number_map(number_str: &str) -> Result { - number_str.parse::().map(|n| 2 * n) +fn multiply(first_number_str: &str, second_number_str: &str) -> Result { + first_number_str.parse::().and_then(|first_number| { + second_number_str.parse::().map(|second_number| first_number * second_number) + }) } fn print(result: Result) { @@ -40,11 +72,11 @@ fn print(result: Result) { fn main() { // This still presents a reasonable answer. - let twenty = double_number("10"); + let twenty = multiply("10", "2"); print(twenty); // The following now provides a much more helpful error message. - let tt = double_number_map("t"); + let tt = multiply("t", "2"); print(tt); } ``` From a3da46826efb588b0adcf67f1e69d9e98c587d7c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 20 Sep 2017 20:39:14 -0600 Subject: [PATCH 0681/1122] Consolidate multiple-errors sections --- src/SUMMARY.md | 6 +++--- src/error/{ => multiple_error_types}/boxing_errors.md | 0 src/error/{ => multiple_error_types}/define_error_type.md | 0 .../{ => multiple_error_types}/reenter_question_mark.md | 0 src/error/result/enter_question_mark.md | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename src/error/{ => multiple_error_types}/boxing_errors.md (100%) rename src/error/{ => multiple_error_types}/define_error_type.md (100%) rename src/error/{ => multiple_error_types}/reenter_question_mark.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1f59299861..23977ec916 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -140,9 +140,9 @@ - [Early returns](error/result/early_returns.md) - [Introducing `?`](error/result/enter_question_mark.md) - [Multiple error types](error/multiple_error_types.md) - - [Defining an error type](error/define_error_type.md) - - [Other uses of `?`](error/reenter_question_mark.md) - - [`Box`ing errors](error/boxing_errors.md) + - [Defining an error type](error/multiple_error_types/define_error_type.md) + - [Other uses of `?`](error/multiple_error_types/reenter_question_mark.md) + - [`Box`ing errors](error/multiple_error_types/boxing_errors.md) - [Iterating over `Result`s](error/iter_result.md) - [Std library types](std.md) diff --git a/src/error/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md similarity index 100% rename from src/error/boxing_errors.md rename to src/error/multiple_error_types/boxing_errors.md diff --git a/src/error/define_error_type.md b/src/error/multiple_error_types/define_error_type.md similarity index 100% rename from src/error/define_error_type.md rename to src/error/multiple_error_types/define_error_type.md diff --git a/src/error/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md similarity index 100% rename from src/error/reenter_question_mark.md rename to src/error/multiple_error_types/reenter_question_mark.md diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index 265aa38204..e3f227fc2e 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -69,4 +69,4 @@ fn main() { [^1]: See [re-enter ?][re_enter_?] for more details. -[re_enter_?]: /error/reenter_question_mark.html +[re_enter_?]: /error/multiple_error_types/reenter_question_mark.html From cd6a71fcd2b620ec8a38b8cb3de8ca0584a2eec8 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 22 Sep 2017 21:11:13 -0600 Subject: [PATCH 0682/1122] Update multiple-error-types section for new flow `option_result.md` is a new page for showing the naiive approach while also included the trick for swapping `Option` to `Result`. `boxing_errors.md` was moved earlier in the material to quickly get the reader to something they can use to get decent results in their application with minimal fuss. This was also part of an effort to remove the use of `Result<_, String>` to avoid the issue of someone jumping into a section they need, seeing it, and using it when there are much better alternatives. `define_error_type.md`s focus was narrowed to just defining errors, leaving wrapping errors to the new `wrap_error.md` page. In addition, some basic traits were added to try to make the example code sufficient for someone jumping into that page just to see how to define an error. Moving `wrap_error.md` to the end also allowed some of the earlier examples to include less boilerplate, minimizing distraction from the point that is trying to be made. Links and examples have been tested. Fixes #901, #902 --- src/SUMMARY.md | 4 +- src/error/multiple_error_types.md | 70 +++----------- .../multiple_error_types/boxing_errors.md | 93 +++++------------- .../multiple_error_types/define_error_type.md | 57 +++++------ .../multiple_error_types/option_result.md | 58 +++++++++++ .../reenter_question_mark.md | 84 +++++++--------- src/error/multiple_error_types/wrap_error.md | 95 +++++++++++++++++++ 7 files changed, 249 insertions(+), 212 deletions(-) create mode 100644 src/error/multiple_error_types/option_result.md create mode 100644 src/error/multiple_error_types/wrap_error.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 23977ec916..2bbe16aebb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -140,9 +140,11 @@ - [Early returns](error/result/early_returns.md) - [Introducing `?`](error/result/enter_question_mark.md) - [Multiple error types](error/multiple_error_types.md) + - [Pulling `Result`s out of `Option`s](error/multiple_error_types/option_result.md) - [Defining an error type](error/multiple_error_types/define_error_type.md) - - [Other uses of `?`](error/multiple_error_types/reenter_question_mark.md) - [`Box`ing errors](error/multiple_error_types/boxing_errors.md) + - [Other uses of `?`](error/multiple_error_types/reenter_question_mark.md) + - [Wrapping errors](error/multiple_error_types/wrap_error.md) - [Iterating over `Result`s](error/iter_result.md) - [Std library types](std.md) diff --git a/src/error/multiple_error_types.md b/src/error/multiple_error_types.md index 01e5b9b639..610bbfcb84 100644 --- a/src/error/multiple_error_types.md +++ b/src/error/multiple_error_types.md @@ -1,80 +1,36 @@ # Multiple error types -The previous examples have always been very convenient; `Result`s interact -with other `Result`s and `Option`s interact with other `Option`s. +The previous examples have always been very convenient; `Result`s interact +with other `Result`s and `Option`s interact with other `Option`s. -Sometimes an `Option` needs to interact with a `Result`, or a -`Result` needs to interact with a `Result`. In those -cases, we want to manage our different error types in a way that makes them +Sometimes an `Option` needs to interact with a `Result`, or a +`Result` needs to interact with a `Result`. In those +cases, we want to manage our different error types in a way that makes them composable and easy to interact with. -In the following code, two instances of `unwrap` generate different error -types. `Vec::first` returns an `Option`, while `parse::` returns a +In the following code, two instances of `unwrap` generate different error +types. `Vec::first` returns an `Option`, while `parse::` returns a `Result`: -```rust,ignore +```rust,editable,ignore,mdbook-runnable fn double_first(vec: Vec<&str>) -> i32 { let first = vec.first().unwrap(); // Generate error 1 2 * first.parse::().unwrap() // Generate error 2 } fn main() { + let numbers = vec!["42", "93", "18"]; let empty = vec![]; let strings = vec!["tofu", "93", "18"]; + println!("The first doubled is {}", double_first(numbers)); + println!("The first doubled is {}", double_first(empty)); // Error 1: the input vector is empty println!("The first doubled is {}", double_first(strings)); - // Error 2: the element doesn't parse to a number -} -``` - -Using our knowledge of combinators, we can rewrite the above to explicitly -handle errors. Since two different types of errors can occur, we need to -convert them to a common type such as a `String`. - -To do so, we convert both the `Option` and `Result` into `Result`s, and -then map their errors to the same type: - -```rust,editable -// Use `String` as our error type -type Result = std::result::Result; - -fn double_first(vec: Vec<&str>) -> Result { - vec.first() - // Convert the `Option` to a `Result` if there is a value. - // Otherwise, provide an `Err` containing this `String`. - .ok_or("Please use a vector with at least one element.".to_owned()) - .and_then(|s| s.parse::() - // Map any errors that `parse` yields to `String`. - .map_err(|e| e.to_string()) - // `Result` is the new return type, - // and we can now double the number inside. - .map(|i| 2 * i)) -} - -fn print(result: Result) { - match result { - Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - let empty = vec![]; - let strings = vec!["tofu", "93", "18"]; - - print(double_first(empty)); - print(double_first(strings)); + // Error 2: the element doesn't parse to a number } ``` -In the next section, we'll see an alternate method of explicitly handling these errors. - -### See Also: - -[`Option::ok_or`][okor], [`Result::map_err`][maperr] - -[okor]: https://doc.rust-lang.org/std/option/enum.Option.html#method.ok_or -[maperr]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err +Over the next sections, we'll see several strategies for handling these kind of problems. diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index 7c31bb5af7..6257adaff3 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -1,39 +1,12 @@ # `Box`ing errors -By implementing `Display` and `From` for our error type, we enabled -almost all of the `std` library error handling tools. However, we missed -something: the ability to easily `Box` our error type. +A way to write simple code while preserving the original errors is to [`Box`][box] +them. The drawback is that the underlying error type is only known at runtime and not +[statically determined][dynamic_dispatch]. -The `std` library automatically converts any type that implements the -`Error` trait into the trait object `Box`, via `From`. To a -library user, this conveniently allows the following: - -```rust,ignore -fn foo(...) -> Result> { ... } -``` - -A user may use any variety of external libraries which each provide their own error -types. In order to define a valid `Result` type, the user has a few choices: - -* define a new wrapper error type around the library's error types -* convert the error types to `String` or another intermediate choice -* `Box` the error types into `Box` via type erasure - -"Boxing" the error type is a common choice. The drawback is that the -underlying error type is only known at runtime and not -[statically determined][dynamic_dispatch]. As mentioned above, all that -needs to be done is to implement the `Error` trait: - -```rust,ignore -trait Error: Debug + Display { - fn description(&self) -> &str; - fn cause(&self) -> Option<&Error>; -} -``` - -With this implementation, let's look at our most recent example. Note that -it is just as valid with the error type of `Box` as it was before -with `DoubleError`: +The stdlib helps in boxing our errors by having `Box` implement conversion from +any type that implements the `Error` trait into the trait object `Box`, +via [`From`][from]. ```rust,editable use std::error; @@ -43,56 +16,32 @@ use std::num::ParseIntError; // Change the alias to `Box`. type Result = std::result::Result>; -#[derive(Debug)] -enum DoubleError { - EmptyVec, - Parse(ParseIntError), -} +#[derive(Debug, Clone)] +struct EmptyVec; -impl From for DoubleError { - fn from(err: ParseIntError) -> DoubleError { - DoubleError::Parse(err) - } -} - -impl fmt::Display for DoubleError { +impl fmt::Display for EmptyVec { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - DoubleError::Parse(ref e) => e.fmt(f), - } + write!(f, "invalid first item to double") } } -impl error::Error for DoubleError { +impl error::Error for EmptyVec { fn description(&self) -> &str { - match *self { - // A very short description of the error. Doesn't need to be the - // same as `Display`. - DoubleError::EmptyVec => "empty vectors not allowed", - // This already impls `Error`, so defer to its own implementation. - DoubleError::Parse(ref e) => e.description(), - } + "invalid first item to double" } fn cause(&self) -> Option<&error::Error> { - match *self { - // No underlying cause so return `None`. - DoubleError::EmptyVec => None, - // The cause is the underlying implementation error type. Is implicitly - // cast to the trait object `&error::Error`. This works because the - // underlying type already implements the `Error` trait. - DoubleError::Parse(ref e) => Some(e), - } + // Generic error, underlying cause isn't tracked. + None } } fn double_first(vec: Vec<&str>) -> Result { - let first = vec.first().ok_or(DoubleError::EmptyVec)?; - let parsed = first.parse::()?; - - Ok(2 * parsed) + vec.first() + .ok_or_else(|| EmptyVec.into()) // Converts to Box + .and_then(|s| s.parse::() + .map_err(|e| e.into()) // Converts to Box + .map(|i| 2 * i)) } fn print(result: Result) { @@ -103,7 +52,7 @@ fn print(result: Result) { } fn main() { - let numbers = vec!["93", "18"]; + let numbers = vec!["42", "93", "18"]; let empty = vec![]; let strings = vec!["tofu", "93", "18"]; @@ -117,5 +66,7 @@ fn main() { [Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] +[box]: https://doc.rust-lang.org/std/boxed/struct.Box.html [dynamic_dispatch]: https://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch [error]: https://doc.rust-lang.org/std/error/trait.Error.html +[from]: https://doc.rust-lang.org/std/convert/trait.From.html diff --git a/src/error/multiple_error_types/define_error_type.md b/src/error/multiple_error_types/define_error_type.md index 83eba5a8b8..fdd9e80b00 100644 --- a/src/error/multiple_error_types/define_error_type.md +++ b/src/error/multiple_error_types/define_error_type.md @@ -1,5 +1,8 @@ # Defining an error type +Sometimes it simplifies the code to mask all of the different errors with a +single type of error. We'll show this with a custom error. + Rust allows us to define our own error types. In general, a "good" error type: * Represents different errors with the same type @@ -10,29 +13,20 @@ Rust allows us to define our own error types. In general, a "good" error type: * Can hold information about the error - Good: `Err(BadChar(c, position))` - Bad: `Err("+ cannot be used here".to_owned())` - -Note that a `String` (which we've been using up to this point) fulfills the -first two criteria, but not the last two. This makes `String` errors verbose -to create and difficult to react to. It should not be necessary to pollute -logic heavy code with `String` formatting simply to display nicely. +* Composes well with other errors ```rust,editable -use std::num::ParseIntError; +use std::error; use std::fmt; +use std::num::ParseIntError; type Result = std::result::Result; -#[derive(Debug)] -// Define our error types. These may be customized for our error handling cases. +#[derive(Debug, Clone)] +// Define our error types. These may be customized for our error handling cases. // Now we will be able to write our own errors, defer to an underlying error // implementation, or do something in between. -enum DoubleError { - // We don't require any extra info to detail this error. - EmptyVec, - // We will defer to the parse error implementation for their error. - // Supplying extra info requires adding more data to the type. - Parse(ParseIntError), -} +struct DoubleError; // Generation of an error is completely separate from how it is displayed. // There's no need to be concerned about cluttering complex logic with the display style. @@ -41,22 +35,29 @@ enum DoubleError { // which string failed to parse without modifying our types to carry that information. impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - // This is a wrapper, so defer to the underlying types' implementation of `fmt`. - DoubleError::Parse(ref e) => e.fmt(f), - } + write!(f, "invalid first item to double") + } +} + +// This is important for other errors to wrap this one. +impl error::Error for DoubleError { + fn description(&self) -> &str { + "invalid first item to double" + } + + fn cause(&self) -> Option<&error::Error> { + // Generic error, underlying cause isn't tracked. + None } } fn double_first(vec: Vec<&str>) -> Result { vec.first() // Change the error to our new type. - .ok_or(DoubleError::EmptyVec) + .ok_or(DoubleError) .and_then(|s| s.parse::() // Update to the new error type here also. - .map_err(DoubleError::Parse) + .map_err(|_| DoubleError) .map(|i| 2 * i)) } @@ -68,7 +69,7 @@ fn print(result: Result) { } fn main() { - let numbers = vec!["93", "18"]; + let numbers = vec!["42", "93", "18"]; let empty = vec![]; let strings = vec!["tofu", "93", "18"]; @@ -77,11 +78,3 @@ fn main() { print(double_first(strings)); } ``` - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: https://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: https://doc.rust-lang.org/std/io/type.Result.html -[inplace]: /error/option_with_result/result_string_errors.html diff --git a/src/error/multiple_error_types/option_result.md b/src/error/multiple_error_types/option_result.md new file mode 100644 index 0000000000..23bec6ab6a --- /dev/null +++ b/src/error/multiple_error_types/option_result.md @@ -0,0 +1,58 @@ +# Pulling `Result`s out of `Option`s + +The most basic way of handling mixed error types is to just embed them in each +other. + +```rust,editable +use std::num::ParseIntError; + +fn double_first(vec: Vec<&str>) -> Option> { + vec.first().map(|first| { + first.parse::().map(|n| 2 * n) + }) +} + +fn main() { + let numbers = vec!["42", "93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {:?}", double_first(numbers)); + + println!("The first doubled is {:?}", double_first(empty)); + // Error 1: the input vector is empty + + println!("The first doubled is {:?}", double_first(strings)); + // Error 2: the element doesn't parse to a number +} +``` + +There are times when we'll want to stop processing on errors (like with +[`?`][enter_question_mark]) but keep going when the `Option` is `None`. A +couple of combinators come in handy to swap the `Result` and `Option`. + +```rust,editable +use std::num::ParseIntError; + +fn double_first(vec: Vec<&str>) -> Result, ParseIntError> { + let opt = vec.first().map(|first| { + first.parse::().map(|n| 2 * n) + }); + + let opt = opt.map_or(Ok(None), |r| r.map(Some))?; + + Ok(opt) +} + +fn main() { + let numbers = vec!["42", "93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {:?}", double_first(numbers)); + println!("The first doubled is {:?}", double_first(empty)); + println!("The first doubled is {:?}", double_first(strings)); +} +``` + +[enter_question_mark]: /error/result/enter_question_mark.html diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index 76ccfcb036..4df124aa81 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -1,65 +1,60 @@ # Other uses of `?` -Notice in the previous example that our immediate reaction to calling -`parse` is to `map` the error from a library error into our new custom -error type: +Notice in the previous example that our immediate reaction to calling +`parse` is to `map` the error from a library error into a boxed +error: ```rust,ignore -.and_then(|s| s.parse::()) - .map_err(DoubleError::Parse) +.and_then(|s| s.parse::() + .map_err(|e| e.into()) ``` -Since this is a simple and common operation, it would be convenient if it -could be elided. Alas, because `and_then` is not sufficiently flexible, it +Since this is a simple and common operation, it would be convenient if it +could be elided. Alas, because `and_then` is not sufficiently flexible, it cannot. However, we can instead use `?`. -`?` was previously explained as either `unwrap` or `return Err(err)`. -This is only mostly true. It actually means `unwrap` or -`return Err(From::from(err))`. Since `From::from` is a conversion utility -between different types, this means that if you `?` where the error is +`?` was previously explained as either `unwrap` or `return Err(err)`. +This is only mostly true. It actually means `unwrap` or +`return Err(From::from(err))`. Since `From::from` is a conversion utility +between different types, this means that if you `?` where the error is convertible to the return type, it will convert automatically. -Here, we rewrite the previous example using `?`. As a result, the +Here, we rewrite the previous example using `?`. As a result, the `map_err` will go away when `From::from` is implemented for our error type: ```rust,editable -use std::num::ParseIntError; +use std::error; use std::fmt; +use std::num::ParseIntError; -type Result = std::result::Result; +// Change the alias to `Box`. +type Result = std::result::Result>; #[derive(Debug)] -enum DoubleError { - EmptyVec, - Parse(ParseIntError), -} +struct EmptyVec; -// Implement the conversion from `ParseIntError` to `DoubleError`. -// This will be automatically called by `?` if a `ParseIntError` -// needs to be converted into a `DoubleError`. -impl From for DoubleError { - fn from(err: ParseIntError) -> DoubleError { - DoubleError::Parse(err) +impl fmt::Display for EmptyVec { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "invalid first item to double") } } -impl fmt::Display for DoubleError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DoubleError::EmptyVec => - write!(f, "please use a vector with at least one element"), - DoubleError::Parse(ref e) => e.fmt(f), - } +impl error::Error for EmptyVec { + fn description(&self) -> &str { + "invalid first item to double" + } + + fn cause(&self) -> Option<&error::Error> { + // Generic error, underlying cause isn't tracked. + None } } // The same structure as before but rather than chain all `Results` // and `Options` along, we `?` to get the inner value out immediately. fn double_first(vec: Vec<&str>) -> Result { - // Still convert to `Result` by stating how to convert `None`. - let first = vec.first().ok_or(DoubleError::EmptyVec)?; + let first = vec.first().ok_or(EmptyVec)?; let parsed = first.parse::()?; - Ok(2 * parsed) } @@ -71,7 +66,7 @@ fn print(result: Result) { } fn main() { - let numbers = vec!["93", "18"]; + let numbers = vec!["42", "93", "18"]; let empty = vec![]; let strings = vec!["tofu", "93", "18"]; @@ -81,24 +76,11 @@ fn main() { } ``` -This is actually fairly clean now. Compared with the original `panic`, it -is very similar to replacing the `unwrap` calls with `?` except that the -return types are `Result`. As a result, they must be destructured at the +This is actually fairly clean now. Compared with the original `panic`, it +is very similar to replacing the `unwrap` calls with `?` except that the +return types are `Result`. As a result, they must be destructured at the top level. -Note that you should not expect error handling of this sort to always -replace `unwrap`. This type of error handling tripled our line count and -cannot really be considered simple (even when heavily biased by the small -code size). - -Indeed, moving a 1000 line library from `unwrap` to more proper error -handling might be feasible in an additional 100 lines of code. However, the -necessary refactoring would most definitely not be trivial. - -Many libraries might get away with only implementing `Display` and -adding `From` on an as needed basis. However, more serious libraries will -eventually need to meet higher expectations of error handling implementation. - ### See also: [`From::from`][from] and [`?`][q_mark] diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md new file mode 100644 index 0000000000..074f23ee02 --- /dev/null +++ b/src/error/multiple_error_types/wrap_error.md @@ -0,0 +1,95 @@ +# Wrapping errors + +An alternative to boxing errors is to wrap them in your own error type. + +```rust,editable +use std::error; +use std::num::ParseIntError; +use std::fmt; + +type Result = std::result::Result; + +#[derive(Debug)] +enum DoubleError { + EmptyVec, + // We will defer to the parse error implementation for their error. + // Supplying extra info requires adding more data to the type. + Parse(ParseIntError), +} + +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + // This is a wrapper, so defer to the underlying types' implementation of `fmt`. + DoubleError::Parse(ref e) => e.fmt(f), + } + } +} + +impl error::Error for DoubleError { + fn description(&self) -> &str { + match *self { + DoubleError::EmptyVec => "empty vectors not allowed", + // This already impls `Error`, so defer to its own implementation. + DoubleError::Parse(ref e) => e.description(), + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + DoubleError::EmptyVec => None, + // The cause is the underlying implementation error type. Is implicitly + // cast to the trait object `&error::Error`. This works because the + // underlying type already implements the `Error` trait. + DoubleError::Parse(ref e) => Some(e), + } + } +} + +// Implement the conversion from `ParseIntError` to `DoubleError`. +// This will be automatically called by `?` if a `ParseIntError` +// needs to be converted into a `DoubleError`. +impl From for DoubleError { + fn from(err: ParseIntError) -> DoubleError { + DoubleError::Parse(err) + } +} + +fn double_first(vec: Vec<&str>) -> Result { + let first = vec.first().ok_or(DoubleError::EmptyVec)?; + let parsed = first.parse::()?; + + Ok(2 * parsed) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + let numbers = vec!["42", "93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} +``` + +This adds a bit more boilerplate for handling errors and might not be needed in +all applications. There are some libraries that can take care of the boiler +plate for you. + +### See also: + +[`From::from`][from] and [`Enums`][enums] + +[from]: https://doc.rust-lang.org/std/convert/trait.From.html +[q_mark]: https://doc.rust-lang.org/reference/expressions.html#the--operator +[enums]: /custom_types/enum.html From 96ec1f536de474ef9e612f39d013d1b37332b706 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 22 Sep 2017 21:18:00 -0600 Subject: [PATCH 0683/1122] Fix reference to Result type --- src/error/result/result_map.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/result/result_map.md b/src/error/result/result_map.md index 5bc72fbe67..24537c3189 100644 --- a/src/error/result/result_map.md +++ b/src/error/result/result_map.md @@ -49,7 +49,7 @@ fn main() { ``` Luckily, `Option`'s `map`, `and_then`, and many other combinators are also -implemented for `Result`. [`enum.Result`][result] contains a complete listing. +implemented for `Result`. [`Result`][result] contains a complete listing. ```rust,editable use std::num::ParseIntError; From fc3f5b65dd5438db2a4e522e91f7418662e772b2 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 24 Sep 2017 19:44:22 -0400 Subject: [PATCH 0684/1122] Editable any Was this intended? --- src/fn/closures/closure_examples/iter_any.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/closures/closure_examples/iter_any.md b/src/fn/closures/closure_examples/iter_any.md index 65078540ee..1fb64e9707 100644 --- a/src/fn/closures/closure_examples/iter_any.md +++ b/src/fn/closures/closure_examples/iter_any.md @@ -19,7 +19,7 @@ pub trait Iterator { } ``` -```rust,ignore +```rust,editable fn main() { let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; From 16c0a677a6fd9ca7960382582f64e33a5a1b2647 Mon Sep 17 00:00:00 2001 From: Vishal Sodani Date: Wed, 27 Sep 2017 13:08:16 +0530 Subject: [PATCH 0685/1122] Add summary of each chapter --- src/index.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/index.md b/src/index.md index b295932fb5..441e1df121 100644 --- a/src/index.md +++ b/src/index.md @@ -11,6 +11,47 @@ Additionally for the curious, you can also [check out the source code for this s Now let's begin! +- [Hello World](hello.html) - Start with a traditional Hello World program. + +- [Primitives](primitives.html) - Learn about signed integers, unsigned integers and other primitives. + +- [Custom Types](custom_types.html) - `struct` and `enum`. + +- [Variable Bindings](variable_bindings.html) - mutable bindings, scope, shadowing. + +- [Casting](cast.html) - Learn about explicit conversion between types. + +- [Expressions](expression.html) + +- [Flow Control](flow_control.html) - `if`/`else`, `for`, and others. + +- [Functions](fn.html) - Learn about Methods, Closures and High Order Functions. + +- [Modules](mod.html) - Organize code using modules + +- [Crates](crates.html) - A crate is a compilation unit in Rust. Learn to create a library. + +- [Attributes](attribute.html) - An attribute is metadata applied to some module, crate or item. + +- [Generics](generics.html) - Learn about writing a function or data type which can work for multiple types of arguments. + +- [Scoping rules](scope.html) - Scopes play an important part in ownership, borrowing, and lifetimes. + +- [Traits](trait.html) - A trait is a collection of methods defined for an unknown type: `Self` + +- [Macros](macros.html) + +- [Error handling](error.html) - Learn Rust way of handling failures. + +- [Std library types](std.html) - Learn about some custom types provided by `std` library. + +- [Std misc](std_misc.html) - More custom types for file handling, threads. + +- [Meta](meta.html) - Documentation, Testing + +- [Unsafe Operations](unsafe.html) + + [rust]: https://www.rust-lang.org/ [install]: https://www.rust-lang.org/install.html [std]: https://doc.rust-lang.org/std/ From 58f2f711d58dc2a21905a0cf9efae7f21c27728c Mon Sep 17 00:00:00 2001 From: Vishal Sodani Date: Fri, 29 Sep 2017 12:12:02 +0530 Subject: [PATCH 0686/1122] Add example to demonstrate pretty printing --- src/hello/print/print_debug.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index da22677a71..8a0e0e2045 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -51,7 +51,26 @@ fn main() { ``` So `fmt::Debug` definitely makes this printable but sacrifices some -elegance. Manually implementing `fmt::Display` will fix that. +elegance. Rust also provides "pretty printing" with `{:#?}`. + +```rust,editable +#[derive(Debug)] +struct Person<'a> { + name: &'a str, + age: u8 +} + +fn main() { + let name = "Peter"; + let age = 27; + let peter = Person { name, age }; + + // Pretty print + println!("{:#?}", peter); +} +``` + +One can manually implement `fmt::Display` to control the display. ### See also From 30e903b6b9b2ecc3da7db71f47d71cd42d17e08e Mon Sep 17 00:00:00 2001 From: Vishal Sodani Date: Sun, 1 Oct 2017 13:40:06 +0530 Subject: [PATCH 0687/1122] Add semicolon to macros --- src/attribute/cfg.md | 4 ++-- src/attribute/cfg/custom.md | 2 +- src/hello/print/fmt.md | 2 +- src/macros/designators.md | 4 ++-- src/mod/use.md | 2 +- src/primitives/tuples.md | 2 +- src/scope/lifetime/elision.md | 4 ++-- src/std_misc/threads.md | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/attribute/cfg.md b/src/attribute/cfg.md index c2e95728b6..55e0e6ecb9 100644 --- a/src/attribute/cfg.md +++ b/src/attribute/cfg.md @@ -11,13 +11,13 @@ Both utilize identical argument syntax. // This function only gets compiled if the target OS is linux #[cfg(target_os = "linux")] fn are_you_on_linux() { - println!("You are running linux!") + println!("You are running linux!"); } // And this function only gets compiled if the target OS is *not* linux #[cfg(not(target_os = "linux"))] fn are_you_on_linux() { - println!("You are *not* running linux!") + println!("You are *not* running linux!"); } fn main() { diff --git a/src/attribute/cfg/custom.md b/src/attribute/cfg/custom.md index 371aea26ad..90b2a0ee2f 100644 --- a/src/attribute/cfg/custom.md +++ b/src/attribute/cfg/custom.md @@ -6,7 +6,7 @@ custom conditionals must be passed to `rustc` using the `--cfg` flag. ```rust,editable,ignore,mdbook-runnable #[cfg(some_condition)] fn conditional_function() { - println!("condition met!") + println!("condition met!"); } fn main() { diff --git a/src/hello/print/fmt.md b/src/hello/print/fmt.md index e47757b464..b838fd7026 100644 --- a/src/hello/print/fmt.md +++ b/src/hello/print/fmt.md @@ -60,7 +60,7 @@ fn main() { ].iter() { // Switch this to use {} once you've added an implementation // for fmt::Display - println!("{:?}", *color) + println!("{:?}", *color); } } ``` diff --git a/src/macros/designators.md b/src/macros/designators.md index 50d5e42481..a06d1d41a3 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -12,7 +12,7 @@ macro_rules! create_function { fn $func_name() { // The `stringify!` macro converts an `ident` into a string. println!("You called {:?}()", - stringify!($func_name)) + stringify!($func_name)); } ) } @@ -29,7 +29,7 @@ macro_rules! print_result { // `stringify!` will convert the expression *as it is* into a string. println!("{:?} = {:?}", stringify!($expression), - $expression) + $expression); ) } diff --git a/src/mod/use.md b/src/mod/use.md index 658c342e08..9d04b826aa 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -14,7 +14,7 @@ fn function() { mod deeply { pub mod nested { pub fn function() { - println!("called `deeply::nested::function()`") + println!("called `deeply::nested::function()`"); } } } diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index 1a9095d26a..c8586db555 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -57,7 +57,7 @@ fn main() { println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d); let matrix = Matrix(1.1, 1.2, 2.1, 2.2); - println!("{:?}", matrix) + println!("{:?}", matrix); } ``` diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index 1fa3fc25ee..5a5b7f58e7 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -12,11 +12,11 @@ description of elision, see [lifetime elision][elision] in the book. // `elided_input` and `annotated_input` essentially have identical signatures // because the lifetime of `elided_input` is elided by the compiler: fn elided_input(x: &i32) { - println!("`elided_input`: {}", x) + println!("`elided_input`: {}", x); } fn annotated_input<'a>(x: &'a i32) { - println!("`annotated_input`: {}", x) + println!("`annotated_input`: {}", x); } // Similarly, `elided_pass` and `annotated_pass` have identical signatures diff --git a/src/std_misc/threads.md b/src/std_misc/threads.md index c3dd0023ac..7a9b2cf22d 100644 --- a/src/std_misc/threads.md +++ b/src/std_misc/threads.md @@ -16,7 +16,7 @@ fn main() { for i in 0..NTHREADS { // Spin up another thread children.push(thread::spawn(move || { - println!("this is thread number {}", i) + println!("this is thread number {}", i); })); } From 578eb39f2600daad8b0dbf25e1c14a65e8c89b2f Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Tue, 3 Oct 2017 22:46:15 +1100 Subject: [PATCH 0688/1122] Fix some first edition links --- src/error.md | 2 +- src/scope/lifetime/elision.md | 10 +++++----- src/std_misc/threads/testcase_mapreduce.md | 8 ++++---- src/trait/ops.md | 6 +++--- src/unsafe.md | 15 ++++++++------- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/error.md b/src/error.md index c19a7b267a..d51e13f1d6 100644 --- a/src/error.md +++ b/src/error.md @@ -8,4 +8,4 @@ saves the rest of the program from various pitfalls. For a more rigorous discussion of error handling, refer to the error handling section in the [official book][book]. -[book]: https://doc.rust-lang.org/book/error-handling.html +[book]: https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index 5a5b7f58e7..7a0b4a9ae3 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -1,11 +1,11 @@ # elision -Some lifetime patterns are overwelmingly common and so the borrow checker -will implicitly add them to save typing and to improve readability. +Some lifetime patterns are overwelmingly common and so the borrow checker +will implicitly add them to save typing and to improve readability. This process of implicit addition is called elision. Elision exists in Rust solely because these patterns are common. -The following code shows a few examples of elision. For a more comprehensive +The following code shows a few examples of elision. For a more comprehensive description of elision, see [lifetime elision][elision] in the book. ```rust,editable @@ -27,7 +27,7 @@ fn annotated_pass<'a>(x: &'a i32) -> &'a i32 { x } fn main() { let x = 3; - + elided_input(&x); annotated_input(&x); @@ -40,4 +40,4 @@ fn main() { [elision][elision] -[elision]: https://doc.rust-lang.org/book/lifetimes.html#lifetime-elision +[elision]: https://doc.rust-lang.org/book/second-edition/ch10-03-lifetime-syntax.html#lifetime-elision diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index f3d2b6edd5..97aa37a989 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -72,7 +72,7 @@ fn main() { // * takes ownership of its captured variables ('move') and // * returns an unsigned 32-bit integer ('-> u32') // - // Rust is smart enough to infer the '-> u32' from + // Rust is smart enough to infer the '-> u32' from // the closure itself so we could have left that out. // // TODO: try removing the 'move' and see what happens @@ -115,7 +115,7 @@ fn main() { // // we use the "turbofish" ::<> to provide sum() with a type hint. // - // TODO: try without the turbofish, by instead explicitly + // TODO: try without the turbofish, by instead explicitly // specifying the type of intermediate_sums let final_result = intermediate_sums.iter().sum::(); @@ -143,10 +143,10 @@ defined by a static constant at the beginning of the program. [thread]: /std_misc/threads.html [vectors]: /std/vec.html [iterators]: /trait/iter.html -[destructuring]: https://doc.rust-lang.org/book/patterns.html#destructuring +[destructuring]: https://doc.rust-lang.org/book/second-edition/ch18-03-pattern-syntax.html#destructuring-to-break-apart-values [closures]: /fn/closures.html [move]: /scope/move.html -[move_closure]: https://doc.rust-lang.org/book/closures.html#move-closures +[move_closure]: https://doc.rust-lang.org/book/second-edition/ch13-01-closures.html#closures-can-capture-their-environment [turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect [unwrap]: /error/option_unwrap.html [enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate diff --git a/src/trait/ops.md b/src/trait/ops.md index 6de80d8e50..b1d38496fc 100644 --- a/src/trait/ops.md +++ b/src/trait/ops.md @@ -2,8 +2,8 @@ In Rust, many of the operators can be overloaded via traits. That is, some operators can be used to accomplish different tasks based on their input arguments. This is possible -because operators are syntactic sugar for method calls. For example, the `+` operator in -`a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` +because operators are syntactic sugar for method calls. For example, the `+` operator in +`a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. A list of the traits, such as `Add`, that overload operators is available [here][ops]. @@ -58,4 +58,4 @@ fn main() { [add]: https://doc.rust-lang.org/core/ops/trait.Add.html [ops]: https://doc.rust-lang.org/core/ops/ -[syntax]: https://doc.rust-lang.org/book/syntax-index.html +[syntax]:https://doc.rust-lang.org/book/second-edition/appendix-02-operators.html diff --git a/src/unsafe.md b/src/unsafe.md index 3d21cd0e72..f0e5d6c278 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -1,11 +1,10 @@ # Unsafe Operations -As an introduction to this section, to borrow from [the official docs]( -https://doc.rust-lang.org/book/unsafe.html), "one should try to minimize the -amount of unsafe code in a code base." With that in mind, let's get started! -Unsafe blocks in Rust are used to bypass protections put in place by the -compiler; specifically, there are four primary things that unsafe blocks are -used for: +As an introduction to this section, to borrow from [the official docs][unsafe], +"one should try to minimize the amount of unsafe code in a code base." With that +in mind, let's get started! Unsafe blocks in Rust are used to bypass protections +put in place by the compiler; specifically, there are four primary things that +unsafe blocks are used for: * dereferencing raw pointers * calling a function over FFI (but this is covered in [a previous @@ -41,4 +40,6 @@ fn main() { assert!(u == std::mem::transmute::<&str, &[u8]>("123")); } } -``` \ No newline at end of file +``` + +[unsafe]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html From a9e9a20b5daf91ec4824d2c5e813fae560560b3f Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Wed, 4 Oct 2017 08:11:07 +1100 Subject: [PATCH 0689/1122] Added destructuring links --- src/flow_control/match/destructuring.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index c6c2bbc780..6976afd4b0 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -1,3 +1,14 @@ # Destructuring -A `match` block can destructure items in a variety of ways. \ No newline at end of file +A `match` block can destructure items in a variety of ways. + +* [Destructuring Enums](enum) +* [Destructuring Pointers](refs) +* [Destructuring Structutures](struct) +* [Destructuring Tuples](tuple) + + +[enum]: destructuring/destructure_enum.md +[refs]: destructuring/destructure_pointers.md +[struct]: destructuring/destructure_structures.md +[tuple]:destructuring/destructure_tuple.md From 2608cdceda4f652e36bac77c0b06116b0062cec6 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Wed, 4 Oct 2017 08:42:20 +1100 Subject: [PATCH 0690/1122] Added rust cookbook reference for args --- src/std_misc/arg.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md index 5af20a0d48..4d5ba95241 100644 --- a/src/std_misc/arg.md +++ b/src/std_misc/arg.md @@ -1,7 +1,9 @@ # Program arguments +## Standard Library + The command line arguments can be accessed using `std::env::args`, which -returns an iterator that yields a String for each argument: +returns an iterator that yields a `String` for each argument: ```rust,editable use std::env; @@ -24,3 +26,12 @@ $ ./args 1 2 3 My path is ./args. I got 3 arguments: ["1", "2", "3"]. ``` + +## Crates + +Alternatively, there are numerous crates that can provide extra functionality +when creating command line applications. The [Rust Cookbook] exhibits best +practices on how to use one of the more popular command line argument crates, +`clap`. + +[Rust Cookbook]: https://rust-lang-nursery.github.io/rust-cookbook/app.html#ex-clap-basic From d49e235657e019349e2e4dfecae269298640a982 Mon Sep 17 00:00:00 2001 From: Aaklo Xu Date: Wed, 4 Oct 2017 14:27:52 +0800 Subject: [PATCH 0691/1122] 1. Add translation links and licence to README.md 2. Some fix about bash code block in markdown --- README.md | 30 +++++++++++++++++++++++++----- src/mod/split.md | 2 +- src/std/panic.md | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8284257169..632c1f0cc3 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ If you'd like to read Rust by Example, you can visit If you'd like to read it locally, [install Rust], and then: ```bash -> git clone https://github.com/rust-lang/rust-by-example -> cd rust-by-example -> cargo install mdbook -> mdbook build -> mdbook serve +$ git clone https://github.com/rust-lang/rust-by-example +$ cd rust-by-example +$ cargo install mdbook +$ mdbook build +$ mdbook serve ``` [install Rust]: http://rust-lang.org/install.html @@ -29,3 +29,23 @@ read all content offline, however! Please see the [CONTRIBUTING.md] file for more details. [CONTRIBUTING.md]: https://github.com/rust-lang/rust-by-example/blob/master/CONTRIBUTING.md + +## Translations to other languages + +* [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) +* [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) + +## License + +Rust by Example is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Rust by Example by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/src/mod/split.md b/src/mod/split.md index a344c4f97e..16e0a60e1b 100644 --- a/src/mod/split.md +++ b/src/mod/split.md @@ -3,7 +3,7 @@ Modules can be mapped to a file/directory hierarchy. Let's break down the [visibility example][visibility] in files: -```text +```bash $ tree . . |-- my diff --git a/src/std/panic.md b/src/std/panic.md index cf220e8203..e9005ceb07 100644 --- a/src/std/panic.md +++ b/src/std/panic.md @@ -34,7 +34,7 @@ fn main() { Let's check that `panic!` doesn't leak memory. -```text +```bash $ rustc panic.rs && valgrind ./panic ==4401== Memcheck, a memory error detector ==4401== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. From a50fd77e7266c6ec430dbe4db13426527afe9aa9 Mon Sep 17 00:00:00 2001 From: Aaklo Xu Date: Wed, 4 Oct 2017 15:07:35 +0800 Subject: [PATCH 0692/1122] Changed `>` to `$` notation in bash --- CONTRIBUTING.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 414ef0edc5..f8d5e43a74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,10 +48,10 @@ We use the following labels: To build RBE, [install Rust], and then: ```bash -> git clone https://github.com/rust-lang/rust-by-example -> cd rust-by-example -> cargo install mdbook -> mdbook build +$ git clone https://github.com/rust-lang/rust-by-example +$ cd rust-by-example +$ cargo install mdbook +$ mdbook build ``` [install Rust]: http://rust-lang.org/install.html @@ -62,7 +62,7 @@ open the contents in your web browser. To run the tests: ```bash -> mdbook test +$ mdbook test ``` If you're adding a new chapter, you'll need to edit `src\SUMMARY.md` to add it. If From 42164b4b3c73dbd32d6901fb0f75c107b9ae32cf Mon Sep 17 00:00:00 2001 From: mbaeten Date: Thu, 5 Oct 2017 11:05:25 +0200 Subject: [PATCH 0693/1122] Update cast.md Thanks for the great tutorial ;) I thnik this should be u8? --- src/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cast.md b/src/cast.md index 849afdcb66..6b6b08d9d1 100644 --- a/src/cast.md +++ b/src/cast.md @@ -52,7 +52,7 @@ fn main() { // repeating the example above // 1000 as u8 -> 232 - println!("1000 as a i8 is : {}", 1000 as i8); + println!("1000 as a i8 is : {}", 1000 as u8); // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); } From c621fd05c0e69a15d0e98ccba69e72db19bdf531 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Fri, 6 Oct 2017 07:22:52 +1100 Subject: [PATCH 0694/1122] Adding alternate into iter functions --- src/flow_control/for.md | 67 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 0d5f4fc559..bfab6e91d2 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -1,8 +1,10 @@ -# for and range +# for loops -The `for in` construct can be used to iterate through an `Iterator`. +## for and range + +The `for in` construct can be used to iterate through an `Iterator`. One of the easiest ways to create an iterator is to use the range -notation `a..b`. This yields values from `a` (inclusive) to `b` +notation `a..b`. This yields values from `a` (inclusive) to `b` (exclusive) in steps of one. Let's write FizzBuzz using `for` instead of `while`. @@ -24,6 +26,65 @@ fn main() { } ``` +## for and iterators + +The `for in` construct is able to interact with an `Iterator` in several ways. +As discussed in with the [Iterator][iter] trait, if not specified, the `for` +loop will apply the `into_iter` function on the collection provided to convert +the collection into an iterator. This is not the only means to convert a +collection into an iterator however, the other functions available include +`iter` and `iter_mut`. + +These 3 functions will return different views of the data within your +collection. + +* `iter` - This borrows each element of the collection through each iteration. + Thus leaving the collection untouched and available for reuse after the loop. + +```rust, editable +let names = vec!["Bob", "Frank", "Ferris"]; + + for name in names.iter() { + match name { + &"Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } + } +``` + +* `into_iter` - This consumes the collection so that on each iteration the exact + data is provided. Once the collection has been consumed it is no longer + available for reuse as it has been 'moved' within the loop. + +```rust, editable +let names = vec!["Bob", "Frank", "Ferris"]; + +for name in names.into_iter() { + match name { + "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } + } +``` + +* `iter_mut` - This mutably borrows each element of the collection, allowing for + the collection to be modified in place. + +```rust, editable +let mut names = vec!["Bob", "Frank", "Ferris"]; + +for name in names.iter_mut() { + match name { + &mut "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } + } +``` + +In the above snippets note the type of `match` branch, that is the key +difference in the types or iteration. The difference in type then of course +implies differing actions that are able to be performed. + ### See also [Iterator][iter] From 76d348a772543d422748e2a25a6c7de11fdd7ffc Mon Sep 17 00:00:00 2001 From: liyuntao Date: Fri, 6 Oct 2017 10:48:14 +0800 Subject: [PATCH 0695/1122] Fix a small typo in comments --- src/std/result/question_mark.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/result/question_mark.md b/src/std/result/question_mark.md index 4650702722..5415191865 100644 --- a/src/std/result/question_mark.md +++ b/src/std/result/question_mark.md @@ -46,7 +46,7 @@ mod checked { // if `div` "fails", then `DivisionByZero` will be `return`ed let ratio = div(x, y)?; - // if `ln` "fails", then `NegativeLogarithm` will be `return`ed + // if `ln` "fails", then `NonPositiveLogarithm` will be `return`ed let ln = ln(ratio)?; sqrt(ln) From 2b172532deddbbc17f9989b4962361f7295966ad Mon Sep 17 00:00:00 2001 From: Timo Date: Fri, 6 Oct 2017 23:17:10 -0400 Subject: [PATCH 0696/1122] Update cast.md Text printed now reflects code being run. --- src/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cast.md b/src/cast.md index 6b6b08d9d1..95fd686791 100644 --- a/src/cast.md +++ b/src/cast.md @@ -52,7 +52,7 @@ fn main() { // repeating the example above // 1000 as u8 -> 232 - println!("1000 as a i8 is : {}", 1000 as u8); + println!("1000 as a u8 is : {}", 1000 as u8); // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); } From adc1ba832c4796462e24e66a460b2e261060e4dc Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 11 Oct 2017 03:14:43 -0500 Subject: [PATCH 0697/1122] Add newtype idiom section --- src/SUMMARY.md | 1 + src/generics/new_types.md | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/generics/new_types.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2bbe16aebb..7f06eaa881 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -91,6 +91,7 @@ - [Testcase: empty bounds](generics/bounds/testcase_empty.md) - [Multiple bounds](generics/multi_bounds.md) - [Where clauses](generics/where.md) + - [New Type Idiom](generics/new_types.md) - [Associated items](generics/assoc_items.md) - [The Problem](generics/assoc_items/the_problem.md) - [Associated types](generics/assoc_items/types.md) diff --git a/src/generics/new_types.md b/src/generics/new_types.md new file mode 100644 index 0000000000..fd287b0d3b --- /dev/null +++ b/src/generics/new_types.md @@ -0,0 +1,50 @@ +# New Type Idiom +The `newtype` idiom gives compile time guarantees that the right type of value is supplied +to a program. + +For example, an age verification function that checks age in years, *must* be given +a value of type `Years`. + +```rust, editable +struct Years(i64); + +struct Days(i64); + +impl Years { + pub fn to_days(&self) -> Days { + Days(self.0 * 365) + } +} + + +impl Days { + /// truncates partial years + pub fn to_years(&self) -> Years { + Years(self.0 / 365) + } +} + +fn old_enough(age: Years) -> bool { + if age.0 >= 18 { + return true + } + return false +} + +fn main() { + let age = Years(5); + let age_days = age.to_days(); + println!("Old enough {}", old_enough(age)); + println!("Old enough {}", old_enough(age_days.to_years())); + // println!("Old enough {}", old_enough(age_days)); +} +``` + +Uncomment the last print statement to observe that the type supplied must be `Years`. + +### See also: + +[`structs`][struct] + +[struct]: /custom_types/structs.html + From 3a60b379f162f616fb16a3a472c63c4053bd7872 Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 11 Oct 2017 04:36:13 -0500 Subject: [PATCH 0698/1122] Remove unneeded return --- src/generics/new_types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index fd287b0d3b..ab263e1886 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -28,7 +28,7 @@ fn old_enough(age: Years) -> bool { if age.0 >= 18 { return true } - return false + false } fn main() { From a8b7bc7bb142b1a5aa55df38e94824c0cc973776 Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 11 Oct 2017 04:37:48 -0500 Subject: [PATCH 0699/1122] Have old_enough take a reference Not consuming the value --- src/generics/new_types.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index ab263e1886..b011f36837 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -24,7 +24,7 @@ impl Days { } } -fn old_enough(age: Years) -> bool { +fn old_enough(age: &Years) -> bool { if age.0 >= 18 { return true } @@ -34,9 +34,9 @@ fn old_enough(age: Years) -> bool { fn main() { let age = Years(5); let age_days = age.to_days(); - println!("Old enough {}", old_enough(age)); - println!("Old enough {}", old_enough(age_days.to_years())); - // println!("Old enough {}", old_enough(age_days)); + println!("Old enough {}", old_enough(&age)); + println!("Old enough {}", old_enough(&age_days.to_years())); + // println!("Old enough {}", old_enough(&age_days)); } ``` From 3182f90b66eeef96beca103f268cad0e910044d9 Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 11 Oct 2017 15:36:02 -0500 Subject: [PATCH 0700/1122] Markdown formatting fix --- src/generics/new_types.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index b011f36837..8d3cc3495b 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -1,4 +1,5 @@ # New Type Idiom + The `newtype` idiom gives compile time guarantees that the right type of value is supplied to a program. From a005ceddb37bcc6773145534c86a89e6b99f00cb Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Sat, 14 Oct 2017 09:25:59 +1100 Subject: [PATCH 0701/1122] Swapping around Casting chapter to Types --- src/SUMMARY.md | 9 +++++---- src/types.md | 12 ++++++++++++ src/{cast => types}/alias.md | 0 src/{ => types}/cast.md | 6 +++--- src/{cast => types}/inference.md | 0 src/{cast => types}/literals.md | 0 6 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 src/types.md rename src/{cast => types}/alias.md (100%) rename src/{ => types}/cast.md (96%) rename src/{cast => types}/inference.md (100%) rename src/{cast => types}/literals.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7f06eaa881..5356faf1eb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -28,10 +28,11 @@ - [Scope and Shadowing](variable_bindings/scope.md) - [Declare first](variable_bindings/declare.md) -- [Casting](cast.md) - - [Literals](cast/literals.md) - - [Inference](cast/inference.md) - - [Aliasing](cast/alias.md) +- [Types](types.md) + - [Casting](types/cast.md) + - [Literals](types/literals.md) + - [Inference](types/inference.md) + - [Aliasing](types/alias.md) - [Expressions](expression.md) diff --git a/src/types.md b/src/types.md new file mode 100644 index 0000000000..bbe70cc3b3 --- /dev/null +++ b/src/types.md @@ -0,0 +1,12 @@ +# Types + +Rust provides several mechanisms to change or define the type of primitive and user defined types. The following sections cover: +* [Casting] between primitive types +* Specifying the desired type of [literals] +* Using [type inference] +* [Aliasing] types + +[Casting]: types/cast.html +[literals]: types/literals.html +[type inference]: types/inference.html +[Aliasing]: types/alias.html diff --git a/src/cast/alias.md b/src/types/alias.md similarity index 100% rename from src/cast/alias.md rename to src/types/alias.md diff --git a/src/cast.md b/src/types/cast.md similarity index 96% rename from src/cast.md rename to src/types/cast.md index 95fd686791..e455b81f23 100644 --- a/src/cast.md +++ b/src/types/cast.md @@ -24,7 +24,7 @@ fn main() { println!("Casting: {} -> {} -> {}", decimal, integer, character); - // when casting any value to an unsigned type, T, + // when casting any value to an unsigned type, T, // std::T::MAX + 1 is added or subtracted until the value // fits into the new type @@ -41,8 +41,8 @@ fn main() { // For positive numbers, this is the same as the modulus println!("1000 mod 256 is : {}", 1000 % 256); - // When casting to a signed type, the (bitwise) result is the same as - // first casting to the corresponding unsigned type. If the most significant + // When casting to a signed type, the (bitwise) result is the same as + // first casting to the corresponding unsigned type. If the most significant // bit of that value is 1, then the value is negative. // Unless it already fits, of course. diff --git a/src/cast/inference.md b/src/types/inference.md similarity index 100% rename from src/cast/inference.md rename to src/types/inference.md diff --git a/src/cast/literals.md b/src/types/literals.md similarity index 100% rename from src/cast/literals.md rename to src/types/literals.md From 93d3a9e41ad0310c149437912418738352df1199 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Sat, 14 Oct 2017 10:08:02 +1100 Subject: [PATCH 0702/1122] Added From and Into examples --- src/SUMMARY.md | 3 ++ src/conversion.md | 10 +++++ src/conversion/from_into.md | 76 +++++++++++++++++++++++++++++++++++++ src/types.md | 3 +- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/conversion.md create mode 100644 src/conversion/from_into.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5356faf1eb..a037a6faec 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -34,6 +34,9 @@ - [Inference](types/inference.md) - [Aliasing](types/alias.md) +- [Conversion](conversion.md) + - [From and Into](conversion/from_into.md) + - [Expressions](expression.md) - [Flow Control](flow_control.md) diff --git a/src/conversion.md b/src/conversion.md new file mode 100644 index 0000000000..f7f950ce32 --- /dev/null +++ b/src/conversion.md @@ -0,0 +1,10 @@ +# Conversion + +Rust addresses conversion between types by the use of [traits]. The generic +conversions will use the [`From`] and [`Into`] traits. However there are more +specific ones for the more common cases, in particular when converting to and +from `String`s. + +[traits]: trait.html +[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html +[`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html diff --git a/src/conversion/from_into.md b/src/conversion/from_into.md new file mode 100644 index 0000000000..c27645a1c8 --- /dev/null +++ b/src/conversion/from_into.md @@ -0,0 +1,76 @@ +# `From` and `Into` + +The [`From`] and [`Into`] traits are inherently linked, and this is actually part of +its implementation. If you are able to convert type A from type B, then it +should be easy to believe that we should be able to convert type B to type A. + +## `From` + +The [`From`] trait allows for a type to define how to create itself from another +type, hence providing a very simple mechanism for converting between several +types. There are numerous implementations of this trait within the standard +library for conversion of primitive and common types. + +For example we can easily convert a `str` into a `String` + +```rust +let my_str = "hello"; +let my_string = String::from(my_str); +``` + +We can do similar for defining a conversion for our own type. + +```rust,editable +use std::convert::From; + +#[derive(Debug)] +struct Number { + value: i32, +} + +impl From for Number { + fn from(item: i32) -> Self { + Number { value: item } + } +} + +fn main() { + let num = Number::from(30); + println!("My number is {:?}", num); +} +``` + +## `Into` + +The [`Into`] trait is simply the reciprocal of the `From` trait. That is, if you +have implemented the `From` trait for your type you get the `Into` +implementation for free. + +Using the `Into` trait will typically require specification of the type to +convert into as the compiler is unable to determine this most of the time. +However this is a small trade off considering we get the functionality for free. + +```rust,editable +use std::convert::From; + +#[derive(Debug)] +struct Number { + value: i32, +} + +impl From for Number { + fn from(item: i32) -> Self { + Number { value: item } + } +} + +fn main() { + let int = 5; + // Try removing the type declaration + let num: Number = int.into(); + println!("My number is {:?}", num); +} +``` + +[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html +[`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html diff --git a/src/types.md b/src/types.md index bbe70cc3b3..04088a96f0 100644 --- a/src/types.md +++ b/src/types.md @@ -1,6 +1,7 @@ # Types -Rust provides several mechanisms to change or define the type of primitive and user defined types. The following sections cover: +Rust provides several mechanisms to change or define the type of primitive and +user defined types. The following sections cover: * [Casting] between primitive types * Specifying the desired type of [literals] * Using [type inference] From cca22a2253f17975fb0e4456610cff42a3b9365d Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Sat, 14 Oct 2017 10:31:43 +1100 Subject: [PATCH 0703/1122] Added string conversion --- src/SUMMARY.md | 1 + src/conversion/string.md | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/conversion/string.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a037a6faec..c3add55d48 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -36,6 +36,7 @@ - [Conversion](conversion.md) - [From and Into](conversion/from_into.md) + - [To and From String](conversion/string.md) - [Expressions](expression.md) diff --git a/src/conversion/string.md b/src/conversion/string.md new file mode 100644 index 0000000000..f17794bab2 --- /dev/null +++ b/src/conversion/string.md @@ -0,0 +1,51 @@ +# To and From String + +## `ToString` + +To convert any type to a `String` it is as simple as implementing the [`ToString`] +trait for the type. + +```rust,editable +use std::string::ToString; + +struct Circle { + radius: i32 +} + +impl ToString for Circle { + fn to_string(&self) -> String { + format!("Circle of radius {:?}", self.radius) + } +} + +fn main() { + let circle = Circle { radius: 6 }; + println!("{}", circle.to_string()); +} +``` + +## Parsing a String + +One of the more common types to convert a string into is a number. The idiomatic +approach to this is to use the [`parse`] function and provide the type for the +function to parse the string value into, this can be done either without type +inference or using the 'turbofish' syntax. + +This will convert the string into the type specified so long as the [`FromStr`] +trait is implemented for that type. This is implemented for numerous types +within the standard library. To obtain this functionality on a user defined type +simply implement the [`FromStr`] trait for that type. + +```rust +fn main() { + let parsed: i32 = "5".parse().unwrap(); + let turbo_parsed = "10".parse::().unwrap(); + + let sum = parsed + turbo_parsed; + println!{"Sum: {:?}", sum}; +} +``` + +[`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html +[`parse`]: https://doc.rust-lang.org/std/primitive.str.html#method.parse +[`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html From abbaef0a668bc8293420536fd81be59486429e2a Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Mon, 16 Oct 2017 08:28:17 +1100 Subject: [PATCH 0704/1122] Added github symbol --- theme/index.hbs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/theme/index.hbs b/theme/index.hbs index d0bce85ba6..89dfaaa45b 100644 --- a/theme/index.hbs +++ b/theme/index.hbs @@ -91,6 +91,9 @@

{{ book_title }}

+ + + @@ -140,6 +143,7 @@ $("#edit-button").click(function(){ var editWindow = window.open("https://github.com/rust-lang/rust-by-example/edit/master/src/{{ path }}"); }); + // END - Rust-By-Example customization @@ -177,4 +181,4 @@ - \ No newline at end of file + From 5fc4887459164e5bd48dc4c1c59e352398b15372 Mon Sep 17 00:00:00 2001 From: Cade Colvin Date: Thu, 19 Oct 2017 10:32:34 -0500 Subject: [PATCH 0705/1122] Updated index.md to match SUMMARY.md Replaced 'Casting' in favor of 'Types' as well as added a link to 'Conversion' --- src/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.md b/src/index.md index 441e1df121..d5be9b5e63 100644 --- a/src/index.md +++ b/src/index.md @@ -19,7 +19,9 @@ Now let's begin! - [Variable Bindings](variable_bindings.html) - mutable bindings, scope, shadowing. -- [Casting](cast.html) - Learn about explicit conversion between types. +- [Types](types.html) - Learn about changing and defining types. + +- [Conversion](conversion.html) - [Expressions](expression.html) From f8bf8a5421b3c7964f5b145ab86a7ce4503ca88d Mon Sep 17 00:00:00 2001 From: Jan Solanti Date: Sat, 21 Oct 2017 17:57:20 +0300 Subject: [PATCH 0706/1122] Add subchapter about (byte)string literals --- src/std/str.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/std/str.md b/src/std/str.md index 54261ee602..770b42a370 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -57,5 +57,110 @@ More `str`/`String` methods can be found under the [std::string][string] modules +## Literals and escapes + +There are multiple ways to write string literals with special characters in them. +All result in a similar `&str` so it's best to use the form that is the most +convenient to write. Similarly there are multiple ways to write byte string literals, +which all result in `&[u8; N]`. + +Generally special characters are escaped with a backslash character: `\`. +This way you can add any character to your string, even unprintable ones +and ones that you don't know how to type. If you want a literal backslash, +escape it with another one: `\\` + +String or character literal delimiters occuring within a literal must be escaped: `"\""`, `'\''`. + +```rust,editable +fn main() { + // You can use escapes to write bytes by their hexadecimal values... + let byte_escape = "I'm writing \x52\x75\x73\x74!"; + println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape); + + // ...or Unicode code points. + let unicode_codepoint = "\u{211D}"; + let character_name = "\"DOUBLE-STRUCK CAPITAL R\""; + + println!("Unicode character {} (U+211D) is called {}", + unicode_codepoint, character_name ); + + + let long_string = "String literals + can span multiple lines. + The linebreak and indentation here ->\ + <- can be escaped too!"; + println!("{}", long_string); +} +``` + +Sometimes there are just too many characters that need to be escaped or it's just +much more convenient to write a string out as-is. This is where raw string literals come into play. + +```rust, editable +fn main() { + let raw_str = r"Escapes don't work here: \x3F \u{211D}"; + println!("{}", raw_str); + + // If you need quotes in a raw string, add a pair of #s + let quotes = r#"And then I said: "There is no escape!""#; + println!("{}", quotes); + + // If you need "# in your string, just use more #s in the delimiter. + // There is no limit for the number of #s you can use. + let longer_delimiter = r###"A string with "# in it. And even "##!"###; + println!("{}", longer_delimiter); +} +``` + +Want a string that's not UTF-8? (Remember, `str` and `String` must be valid UTF-8) +Or maybe you want an array of bytes that's mostly text? Byte strings to the rescue! + +```rust, editable +use std::str; + +fn main() { + // Note that this is not actually a &str + let bytestring: &[u8; 20] = b"this is a bytestring"; + + // Byte arrays don't have Display so printing them is a bit limited + println!("A bytestring: {:?}", bytestring); + + // Bytestrings can have byte escapes... + let escaped = b"\x52\x75\x73\x74 as bytes"; + // ...but no unicode escapes + // let escaped = b"\u{211D} is not allowed"; + println!("Some escaped bytes: {:?}", escaped); + + + // Raw bytestrings work just like raw strings + let raw_bytestring = br"\u{211D} is not escaped here"; + println!("{:?}", raw_bytestring); + + // Converting a byte array to str can fail + if let Ok(my_str) = str::from_utf8(raw_bytestring) { + println!("And the same as text: '{}'", my_str); + } + + let quotes = br#"You can also use "fancier" formatting, \ + like with normal raw strings"#; + + // Bytestrings don't have to be UTF-8 + let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82"; // "ようこそ" in SHIFT-JIS + + // But then they can't always be converted to str + match str::from_utf8(shift_jis) { + Ok(my_str) => println!("Conversion successful: '{}'", my_str), + Err(e) => println!("Conversion failed: {:?}", e), + }; +} +``` + +For conversions between character encodings check out the [enconding][encoding-crate] crate. + +A more detailed listing of the ways to write string literals and escape characters +is given in the ['Tokens' chapter][tokens] of the Rust Reference. + [str]: https://doc.rust-lang.org/std/str/ [string]: https://doc.rust-lang.org/std/string/ +[tokens]: https://doc.rust-lang.org/reference/tokens.html +[encoding-crate]: https://crates.io/crates/encoding From 5866ca4545aed1c2966aede10608ff7501c2804d Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 28 Oct 2017 00:25:14 -0500 Subject: [PATCH 0707/1122] Added a chapter on Cargo --- src/SUMMARY.md | 4 +++ src/cargo.md | 12 +++++++ src/cargo/deps.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++ src/cargo/test.md | 22 ++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/cargo.md create mode 100644 src/cargo/deps.md create mode 100644 src/cargo/test.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c3add55d48..118b0bcb10 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -82,6 +82,10 @@ - [Library](crates/lib.md) - [`extern crate`](crates/link.md) +- [Cargo](cargo.md) + - [Dependencies](cargo/deps.md) + - [Tests](cargo/test.md) + - [Attributes](attribute.md) - [`dead_code`](attribute/unused.md) - [Crates](attribute/crate.md) diff --git a/src/cargo.md b/src/cargo.md new file mode 100644 index 0000000000..d312a53ba4 --- /dev/null +++ b/src/cargo.md @@ -0,0 +1,12 @@ +# Cargo + +`cargo` is the official Rust package management tool. It has lots of really +useful features to improve code quality and developer velocity! These include + +- Dependency management and integration with [crates.io](https://crates.io) (the + official Rust package registry) +- Awareness of unit tests +- Awareness of benchmarks + +This chapter will go through some quick basics, but you can find the +comprehensive docs [here](http://doc.crates.io/index.html). diff --git a/src/cargo/deps.md b/src/cargo/deps.md new file mode 100644 index 0000000000..0a2c2692c9 --- /dev/null +++ b/src/cargo/deps.md @@ -0,0 +1,88 @@ +# Dependencies + +Most programs have dependencies on some libraries. If you have ever managed +dependencies by hand, you know how much of a pain this. Luckily, the Rust +ecosystem comes standard with `cargo`! `cargo` can manage dependcies for a +project. + +To create a new Rust project, + +```sh +# A binary +cargo new --bin foo + +# OR A library +cargo new foo +``` + +For the rest of this chapter, I will assume we are making a binary, rather than +a library, but all of the concepts are the same. + +After the above commands, you should see something like this: + +``` +foo +├── Cargo.toml +└── src + └── main.rs +``` + +The `main.rs` is the root source file for your new project -- nothing new there. +The `Cargo.toml` is the config file for `cargo` for this project (`foo`). If you +look inside it, you should see something like this: + +```toml +[package] +name = "foo" +version = "0.1.0" +authors = ["mark"] + +[dependencies] +``` + +You can read more extensively about all of the available configuration options +[here](http://doc.crates.io/manifest.html). + +The `name` field under `package` determines the name of the project. This is +used by `crates.io` if you publish the crate (more later). It is also the name +of the output binary when you compile. + +The `version` field is a crate version number using [Semantic +Versioning](http://semver.org/). + +The `authors` field is a list of authors used when publishing the crate. + +The `dependencies` section lets you add a dependency for your project. + +For example, suppose that I want my program to have a great CLI. You can find +lots of great packages on [crates.io](https://crates.io) (the official Rust +package registry). One popular choice is [clap](https://crates.io/crates/clap). +As of this writing, the most recent published version of `clap` is `2.27.1`. To +add a dependency to our program, we can simply add the following to our +`Cargo.toml` under `dependencies`: `clap = "2.27.1"`. And of course, `extern +crate clap` in `main.rs`, just like normal. And that's it! You can start using +`clap` in your program. + +`cargo` also supports other types of dependencies. Here is just a small +sampling. You can find out more +[here](http://doc.crates.io/specifying-dependencies.html). + +```toml +[package] +name = "foo" +version = "0.1.0" +authors = ["mark"] + +[dependencies] +clap = "2.27.1" # from crates.io +rand = { git = "https://github.com/rust-lang-nursery/rand" } # from online repo +bar = { path = "../bar" } # from a path in the local filesystem +``` + +To build our project we can execute `cargo build` anywhere in the project +directory (including subdirectories!). We can also do `cargo run` to build and +run. Notice that these commands will resolve all dependencies, download crates +if needed, and build everything, including your crate. (Note that it only +rebuilds what it has not already built, similar to `make`). + +Voila! That's all there is too it! diff --git a/src/cargo/test.md b/src/cargo/test.md new file mode 100644 index 0000000000..86a20f5bfe --- /dev/null +++ b/src/cargo/test.md @@ -0,0 +1,22 @@ +# Testing + +As we know testing is integral to any piece of software! Rust has first-class +support for unit and integration testing ([see that chapter for +more](https://rustbyexample.com/meta/test.html)). `cargo` naturally provides an +easy way to run all of your tests! + +```sh +cargo test +``` + +or to run a specific test + +```sh +cargo test test_foo +``` + +You should see output like this: + +``` +TODO TODO TODO (this is not what you will actually see) +``` From 6987a6031c7e879644728757cb154f3690ec46da Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Oct 2017 15:17:38 -0500 Subject: [PATCH 0708/1122] Added to the macros chapter to explain why/when you would use macros --- src/SUMMARY.md | 1 + src/macros.md | 20 +++++++++++++++++++- src/macros/dsl.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/macros/dsl.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c3add55d48..85b1f2e57a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -134,6 +134,7 @@ - [Overload](macros/overload.md) - [Repeat](macros/repeat.md) - [DRY (Don't Repeat Yourself)](macros/dry.md) + - [DSL (Domain Specific Languages)](macros/dsl.md) - [Error handling](error.md) - [`panic`](error/panic.md) diff --git a/src/macros.md b/src/macros.md index 9f5a7c4276..5bd3596bda 100644 --- a/src/macros.md +++ b/src/macros.md @@ -4,6 +4,9 @@ Rust provides a powerful macro system that allows metaprogramming. As you've seen in previous chapters, macros look like functions, except that their name ends with a bang `!`, but instead of generating a function call, macros are expanded into source code that gets compiled with the rest of the program. +However, unlike macros in C and other languages, Rust macros are expanded into +abstract syntax trees, rather than string preprocessing, so you don't get +unexpected precedence bugs. Macros are created using the `macro_rules!` macro. @@ -21,4 +24,19 @@ fn main() { // This call will expand into `println!("Hello");` say_hello!() } -``` \ No newline at end of file +``` + +So why are macros useful? + +1. Don't repeat yourself. There are many cases where you may need similar + functionality in multiple places but with different types. Often, writing a + macro is a useful wait to avoid repeating code. (More on this later) + +2. Domain-specific languages. Macros allow you to define special syntax for a + specific purpose. (More on this later) + +3. Variadic interfaces. Sometime you want to define an interface that takes a + variable number of arguments. An example is `println!` which could take any + number of arguments, depending on the format string!. + +Each of these is addressed in a subchapter. diff --git a/src/macros/dsl.md b/src/macros/dsl.md new file mode 100644 index 0000000000..bce3aa4ada --- /dev/null +++ b/src/macros/dsl.md @@ -0,0 +1,47 @@ +# Domain Specific Languages (DSLs) + +A DSL is a mini "language" embedded in a Rust macro. It is completely valid +Rust because the macro system expands into normal Rust constructs, but it looks +like a small language. This allows you to define concise or intuitive syntax for +some special functionality (within bounds). + +Suppose that I want to define a little calculator API. I would like to supply +a bunch of expressions and print the results. + +```rust +macro_rules! calculate { + (eval $e:expr) => {{ + { + let val: usize = $e; // Force types to be integers + println!("{} = {}", stringify!{$e}, val); + } + }}; + + (eval $e:expr, $(eval $es:expr),+) => {{ + calculate! { eval $e } + calculate! { $(eval $es),+ } + }}; +} + +fn main() { + calculate! { + eval 1 + 2, // hehehe `eval` is _not_ a Rust keyword! + eval 3 + 4, + eval (2 * 3) + 1 + } +} +``` + +Output: +``` +1 + 2 = 3 +3 + 4 = 7 +(2 * 3) + 1 = 7 +``` + +This was a very simple example, but much more complex interfaces have been +developed, such as [`lazy_static`](https://crates.io/crates/lazy_static) or +[`clap`](https://crates.io/crates/clap). + +Notice that this is also a _variadic_ interface -- that is, it can take an +arbitrary number of arguments (in this case, expressions to `eval`). From 511a95938f799e0b7e82c32a2a7a5a54dc90904e Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Oct 2017 15:44:07 -0500 Subject: [PATCH 0709/1122] Separate DSLs and variadics in macro chapter --- src/SUMMARY.md | 7 ++++--- src/macros.md | 4 +--- src/macros/dsl.md | 23 ++++++++--------------- src/macros/variadics.md | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 src/macros/variadics.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 85b1f2e57a..9b4abe8315 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -130,11 +130,12 @@ - [Clone](trait/clone.md) - [macro_rules!](macros.md) - - [Designators](macros/designators.md) - - [Overload](macros/overload.md) - - [Repeat](macros/repeat.md) + - [Syntax: Designators](macros/designators.md) + - [Syntax: Overload](macros/overload.md) + - [Syntax: Repeat](macros/repeat.md) - [DRY (Don't Repeat Yourself)](macros/dry.md) - [DSL (Domain Specific Languages)](macros/dsl.md) + - [Variadics](macros/variadics.md) - [Error handling](error.md) - [`panic`](error/panic.md) diff --git a/src/macros.md b/src/macros.md index 5bd3596bda..8889d3f6a8 100644 --- a/src/macros.md +++ b/src/macros.md @@ -37,6 +37,4 @@ So why are macros useful? 3. Variadic interfaces. Sometime you want to define an interface that takes a variable number of arguments. An example is `println!` which could take any - number of arguments, depending on the format string!. - -Each of these is addressed in a subchapter. + number of arguments, depending on the format string!. (More on this later) diff --git a/src/macros/dsl.md b/src/macros/dsl.md index bce3aa4ada..cdb08d0162 100644 --- a/src/macros/dsl.md +++ b/src/macros/dsl.md @@ -6,9 +6,9 @@ like a small language. This allows you to define concise or intuitive syntax for some special functionality (within bounds). Suppose that I want to define a little calculator API. I would like to supply -a bunch of expressions and print the results. +an expression an have the output printed to console. -```rust +```rust,editable macro_rules! calculate { (eval $e:expr) => {{ { @@ -16,18 +16,15 @@ macro_rules! calculate { println!("{} = {}", stringify!{$e}, val); } }}; - - (eval $e:expr, $(eval $es:expr),+) => {{ - calculate! { eval $e } - calculate! { $(eval $es),+ } - }}; } fn main() { calculate! { - eval 1 + 2, // hehehe `eval` is _not_ a Rust keyword! - eval 3 + 4, - eval (2 * 3) + 1 + eval 1 + 2 // hehehe `eval` is _not_ a Rust keyword! + } + + calculate! { + eval (1 + 2) * (3 / 4) } } ``` @@ -35,13 +32,9 @@ fn main() { Output: ``` 1 + 2 = 3 -3 + 4 = 7 -(2 * 3) + 1 = 7 +(1 + 2) * (3 / 4) = 0 ``` This was a very simple example, but much more complex interfaces have been developed, such as [`lazy_static`](https://crates.io/crates/lazy_static) or [`clap`](https://crates.io/crates/clap). - -Notice that this is also a _variadic_ interface -- that is, it can take an -arbitrary number of arguments (in this case, expressions to `eval`). diff --git a/src/macros/variadics.md b/src/macros/variadics.md new file mode 100644 index 0000000000..5de3a52d34 --- /dev/null +++ b/src/macros/variadics.md @@ -0,0 +1,40 @@ +# Variadic Interfaces + +A _variadic_ interface takes an arbitrary number of arguments. For example, +`println!` can take an arbitrary number of arguments, as determined by the +format string. + +We can extend our `calculate!` macro from the previous section to be variadic: + +```rust,editable +macro_rules! calculate { + // The pattern for a single `eval` + (eval $e:expr) => {{ + { + let val: usize = $e; // Force types to be integers + println!("{} = {}", stringify!{$e}, val); + } + }}; + + // Decompose multiple `eval`s recursively + (eval $e:expr, $(eval $es:expr),+) => {{ + calculate! { eval $e } + calculate! { $(eval $es),+ } + }}; +} + +fn main() { + calculate! { // Look ma! Variadic `calculate!`! + eval 1 + 2, + eval 3 + 4, + eval (2 * 3) + 1 + } +} +``` + +Output: +``` +1 + 2 = 3 +3 + 4 = 7 +(2 * 3) + 1 = 7 +``` From 970b09b98e7499bb6d89acd7bfe54fa07e1308cb Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Oct 2017 15:48:00 -0500 Subject: [PATCH 0710/1122] Minor reorganization of macros chapter --- src/SUMMARY.md | 7 ++++--- src/macros/syntax.md | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 src/macros/syntax.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9b4abe8315..de7e6f6ee7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -130,9 +130,10 @@ - [Clone](trait/clone.md) - [macro_rules!](macros.md) - - [Syntax: Designators](macros/designators.md) - - [Syntax: Overload](macros/overload.md) - - [Syntax: Repeat](macros/repeat.md) + - [Syntax](macro/syntax.md) + - [Designators](macros/designators.md) + - [Overload](macros/overload.md) + - [Repeat](macros/repeat.md) - [DRY (Don't Repeat Yourself)](macros/dry.md) - [DSL (Domain Specific Languages)](macros/dsl.md) - [Variadics](macros/variadics.md) diff --git a/src/macros/syntax.md b/src/macros/syntax.md new file mode 100644 index 0000000000..c318d9bd41 --- /dev/null +++ b/src/macros/syntax.md @@ -0,0 +1,8 @@ +# Syntax + +In following subsections, we will show how to define macros in Rust. +There are three basic ideas: + +- [Patterns and Designators](designators.md) +- [Overloading](overload.md) +- [Repetition](repeat.md) From 3431de37d69cb2843c112f88f2810498232b6e21 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Wed, 18 Oct 2017 18:26:56 +1100 Subject: [PATCH 0711/1122] Adding destructor. --- src/scope/raii.md | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/scope/raii.md b/src/scope/raii.md index 481e447407..42413c4813 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -2,10 +2,10 @@ Variables in Rust do more than just hold data in the stack: they also *own* resources, e.g. `Box` owns memory in the heap. Rust enforces [RAII][raii] -(Resource Acquisition Is Initialization), so whenever an object goes out of -scope, its destructor is called and its owned resources are freed. +(Resource Acquisition Is Initialization), so whenever an object goes out of +scope, its destructor is called and its owned resources are freed. -This behavior shields against *resource leak* bugs, so you'll never have to +This behavior shields against *resource leak* bugs, so you'll never have to manually free memory or worry about memory leaks again! Here's a quick showcase: ```rust,editable @@ -61,10 +61,36 @@ $ rustc raii.rs && valgrind ./raii No leaks here! +## Destructor + +The notion of a destructor in Rust is provided through the [`Drop`] trait. The +destructor is called when the resource goes out of scope. This trait is not +required to be implemented for every type, only implement it for your type if +you require its own destructor logic. + +Run the below example to see how the [`Drop`] trait works. When the variable in +the `main` function goes out of scope the custom destructor wil be invoked. + +```rust,editable +struct ToDrop; + +impl Drop for ToDrop { + fn drop(&mut self) { + println!("ToDrop is being dropped"); + } +} + +fn main() { + let x = ToDrop; + println!("Made a ToDrop!"); +} +``` + ### See also: [Box][box] [raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization [box]: /std/box.html -[valgrind]: http://valgrind.org/info/ \ No newline at end of file +[valgrind]: http://valgrind.org/info/ +[`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html From 180cf1b7afd9b086210c71b26eaebec7f8bf070c Mon Sep 17 00:00:00 2001 From: Jacqueline Outka Date: Mon, 30 Oct 2017 18:23:46 -0400 Subject: [PATCH 0712/1122] Fixes #890 --- src/attribute/crate.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/attribute/crate.md b/src/attribute/crate.md index 5268aa7242..fb39d8c8fe 100644 --- a/src/attribute/crate.md +++ b/src/attribute/crate.md @@ -4,6 +4,11 @@ The `crate_type` attribute can be used to tell the compiler whether a crate is a binary or a library (and even which type of library), and the `crate_name` attribute can be used to set the name of the crate. +However, it is important to note that the `crate_type` attribute has **no** +effect whatsoever when using Cargo, the Rust package manager. Since Cargo is +used for the majority of Rust projects, this means real-world uses of +`crate-type` are relatively limited. + ```rust,editable // This crate is a library #![crate_type = "lib"] From 6a00b63193f32fe722266fb63cc861a11a584280 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 30 Oct 2017 20:20:15 -0500 Subject: [PATCH 0713/1122] Fix non-ascii chars --- src/cargo/deps.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 0a2c2692c9..7c68c81eaa 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -22,9 +22,9 @@ After the above commands, you should see something like this: ``` foo -├── Cargo.toml -└── src - └── main.rs +|-- Cargo.toml +|-- src + |-- main.rs ``` The `main.rs` is the root source file for your new project -- nothing new there. From 6e3ee159b98a91c67ae2095772b9f5a52bf15fdb Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 30 Oct 2017 20:20:32 -0500 Subject: [PATCH 0714/1122] Finish cargo test subchapter --- src/cargo/test.md | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 86a20f5bfe..8ef4bcca18 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -9,14 +9,42 @@ easy way to run all of your tests! cargo test ``` -or to run a specific test +You should see output like this: + +``` +$ cargo test + Compiling blah v0.1.0 (file:///nobackup/blah) + Finished dev [unoptimized + debuginfo] target(s) in 0.89 secs + Running target/debug/deps/blah-d3b32b97275ec472 + +running 3 tests +test test_bar ... ok +test test_baz ... ok +test test_foo_bar ... ok +test test_foo ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +You can also run tests whose name matches a pattern: ```sh cargo test test_foo ``` -You should see output like this: - ``` -TODO TODO TODO (this is not what you will actually see) +$ cargo test test_foo + Compiling blah v0.1.0 (file:///nobackup/blah) + Finished dev [unoptimized + debuginfo] target(s) in 0.35 secs + Running target/debug/deps/blah-d3b32b97275ec472 + +running 2 tests +test test_foo ... ok +test test_foo_bar ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out ``` + +One word of caution: Cargo may run multiple tests concurrently, so make sure +that they don't race with each other. For example, if they all output to a +file, you should make them write to different files. From bd806423cb2310a11a7e49483953adbd19a6cf26 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 30 Oct 2017 21:35:27 -0500 Subject: [PATCH 0715/1122] Attempt #2 at fixing file listing --- src/cargo/deps.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 7c68c81eaa..6115e771e9 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -20,11 +20,11 @@ a library, but all of the concepts are the same. After the above commands, you should see something like this: -``` +```txt foo -|-- Cargo.toml -|-- src - |-- main.rs +├── Cargo.toml +└── src + └── main.rs ``` The `main.rs` is the root source file for your new project -- nothing new there. From 417e19f88818c6f778325d3258a07dc578969add Mon Sep 17 00:00:00 2001 From: Jacqueline Outka Date: Tue, 31 Oct 2017 18:46:43 -0400 Subject: [PATCH 0716/1122] fix reference to crate_name --- src/attribute/crate.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/attribute/crate.md b/src/attribute/crate.md index fb39d8c8fe..c8a119a8e6 100644 --- a/src/attribute/crate.md +++ b/src/attribute/crate.md @@ -4,10 +4,10 @@ The `crate_type` attribute can be used to tell the compiler whether a crate is a binary or a library (and even which type of library), and the `crate_name` attribute can be used to set the name of the crate. -However, it is important to note that the `crate_type` attribute has **no** -effect whatsoever when using Cargo, the Rust package manager. Since Cargo is -used for the majority of Rust projects, this means real-world uses of -`crate-type` are relatively limited. +However, it is important to note that both the `crate_type` and `crate_name` +attributes have **no** effect whatsoever when using Cargo, the Rust package +manager. Since Cargo is used for the majority of Rust projects, this means +real-world uses of `crate-type` and `crate_name` are relatively limited. ```rust,editable // This crate is a library From 68652ae1ae73af81d6e3f1b36fce5e187f238d2d Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Fri, 3 Nov 2017 22:26:46 +0300 Subject: [PATCH 0717/1122] testing chapter: added unit-testing examples --- src/SUMMARY.md | 4 +- src/index.md | 4 +- src/meta/test.md | 67 ----------- src/testing.md | 22 ++++ src/testing/unit_testing.md | 231 ++++++++++++++++++++++++++++++++++++ 5 files changed, 259 insertions(+), 69 deletions(-) delete mode 100644 src/meta/test.md create mode 100644 src/testing.md create mode 100644 src/testing/unit_testing.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index de7e6f6ee7..57854579f8 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -184,8 +184,10 @@ - [Argument parsing](std_misc/arg/matching.md) - [Foreign Function Interface](std_misc/ffi.md) +- [Testing](testing.md) + - [Unit testing](testing/unit_testing.md) + - [Meta](meta.md) - [Documentation](meta/doc.md) - - [Testing](meta/test.md) - [Unsafe Operations](unsafe.md) diff --git a/src/index.md b/src/index.md index d5be9b5e63..5f3a1ed613 100644 --- a/src/index.md +++ b/src/index.md @@ -49,7 +49,9 @@ Now let's begin! - [Std misc](std_misc.html) - More custom types for file handling, threads. -- [Meta](meta.html) - Documentation, Testing +- [Testing](testing.html) - All sorts of testing in Rust. + +- [Meta](meta.html) - Documentation, Benchmarking. - [Unsafe Operations](unsafe.html) diff --git a/src/meta/test.md b/src/meta/test.md deleted file mode 100644 index e93b425dea..0000000000 --- a/src/meta/test.md +++ /dev/null @@ -1,67 +0,0 @@ -# Testing - -Functions can be tested by using these [attributes][attributes]: - -* `#[test]` marks a function as a unit test. The function must take zero -parameters and return nothing. -* `#[should_panic]` marks a function as a panicking test. - -```rust,editable -// Conditionally compile `main` only when the test-suite is *not* being run. -#[cfg(not(test))] -fn main() { - println!("If you see this, the tests were not compiled nor ran!"); -} - -// Conditionally compile the module `test` only when the test-suite is run. -#[cfg(test)] -mod test { - // A helper function `distance_test` will need. - fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { - ( - (b.0 - a.0).powi(2) + - (b.1 - a.1).powi(2) - ).sqrt() - } - - #[test] - fn distance_test() { - assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt()); - } - - #[test] - #[should_panic] - fn failing_test() { - assert!(1i32 == 2i32); - } -} -``` - -Tests can be run with `cargo test` or `rustc --test`. - -```bash -$ rustc --test unit_test.rs -$ ./unit_test - -running 2 tests -test test::distance_test ... ok -test test::failing_test ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured -``` - -If `--test` were not included, then this would happen - -```bash -$ rustc unit_test.rs -$ ./unit_test -If you see this, the tests were not compiled nor ran! -``` - -### See also: - -[attributes][attributes], [conditional compilation][cfg], and [`mod`][mod]. - -[attributes]: /attribute.html -[cfg]: /attribute/cfg.html -[mod]: /mod.html diff --git a/src/testing.md b/src/testing.md new file mode 100644 index 0000000000..ff8fe811f0 --- /dev/null +++ b/src/testing.md @@ -0,0 +1,22 @@ +# Testing + +Rust is a programming language that cares a lot about correctness and it +includes support for writing software tests within the language itself. + +Testing comes in three "tastes": + +* [Unit][unit] testing. +* Doc testing. +* Integration testing. + +Also Rust has support for spectifying additional dependencies for tests: +* Dev-dependencies. + +## See Also + +* [The Book][doc-testing] chapter on testing +* [API Guidelines][doc-nursery] on doc-testing + +[unit]: ./testing/unit_testing.html +[doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html +[doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md new file mode 100644 index 0000000000..7b471c88b1 --- /dev/null +++ b/src/testing/unit_testing.md @@ -0,0 +1,231 @@ +# Unit testing + +Tests are Rust functions that verify that the non-test code is functioning in +the expected manner. The bodies of test functions typically perform some setup, +run the code we want to test, then assert whether the results are what we +expect. + +Typical scenario for grouping tests - adding `tests` [mod][mod] under with +[attribute][attribute] `#[cfg(test)]`. Test functions are marked with `#[test]` +attribute. + +Tests fail when something in the test function [panics][panic]. There are some +helper [macros][macros]: + +* `assert!(expession)` - panics if expression evaluates to `false`. +* `assert_eq!(left, right)` and `assert_ne!(left, right)` - testing left and + right expressions for equality and inequality respectively. + +```rust,ignore +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + +// This is a really bad adding function, its purpose is to fail in this +// example. +#[allow(dead_code)] +fn bad_add(a: i32, b: i32) -> i32 { + a - b +} + +#[cfg(test)] +mod tests { + // Note as useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + #[test] + fn test_add() { + assert_eq!(add(1, 2), 3); + } + + #[test] + fn test_bad_add() { + // This assert would fire and test will fail. + // Please note, that private functions can be tested too! + assert_eq!(bad_add(1, 2), 3); + } +} +``` + +Tests can be run with `cargo test`. + +```bash +$ cargo test + +running 2 tests +test tests::test_bad_add ... FAILED +test tests::test_add ... ok + +failures: + +---- tests::test_bad_add stdout ---- + thread 'tests::test_bad_add' panicked at 'assertion failed: `(left == right)` + left: `-1`, + right: `3`', src/lib.rs:21:8 +note: Run with `RUST_BACKTRACE=1` for a backtrace. + + +failures: + tests::test_bad_add + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +``` + +## Testing panics + +To check functions that should panic under certain circumstances, use attribute +`#[should_panic]`. This attribute accepts optional parameter `expected = ` with +text of panic message: it helps making checks if function may panic in multiple +ways. + +```rust,ignore +pub fn divide_non_zero_result(a: u32, b: u32) -> u32 { + if b == 0 { + panic!("Divide-by-zero error"); + } else if a < b { + panic!("Divide result is zero"); + } + a / b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_divide() { + assert_eq!(divide_non_zero_result(10, 2), 5); + } + + #[test] + #[should_panic] + fn test_any_panic() { + divide_non_zero_result(1, 0); + } + + #[test] + #[should_panic(expected = "Divide result is zero")] + fn test_specific_panic() { + divide_non_zero_result(1, 10); + } +} +``` + +Running these tests gives us: + +```bash +$ cargo test + +running 3 tests +test tests::test_any_panic ... ok +test tests::test_divide ... ok +test tests::test_specific_panic ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests tmp-test-should-panic + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +## Running specific tests + +To run specific tests one may specify test name to `cargo test` command. + +```bash +$ cargo test test_any_panic +running 1 test +test tests::test_any_panic ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out + + Doc-tests tmp-test-should-panic + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +To run multiple tests one may specify part of a test name that matches all the +tests that should be run. + +```bash +$ cargo test panic +running 2 tests +test tests::test_any_panic ... ok +test tests::test_specific_panic ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out + + Doc-tests tmp-test-should-panic + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +## Ignoring tests + +Tests can be marked with `#[ignore]` attribute to exclude some tests. Or to run +them with command `cargo test -- --ignored` + +```rust +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_add() { + assert_eq!(add(2, 2), 4); + } + + #[test] + fn test_add_hundred() { + assert_eq!(add(100, 2), 102); + assert_eq!(add(2, 100), 102); + } + + #[test] + #[ignore] + fn ignored_test() { + assert_eq!(add(0, 0), 0); + } +} +``` + +```bash +$ cargo test +running 1 test +test tests::ignored_test ... ignored + +test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out + + Doc-tests tmp-ignore + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + +$ cargo test -- --ignored +running 1 test +test tests::ignored_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests tmp-ignore + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +[attribute]: ../attribute.html +[panic]: ../std/panic.html +[macros]: ../macros.html +[mod]: ../mod.html From 4f91ba8c8a882f808db46c7b3303be629f1b01d9 Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sat, 4 Nov 2017 10:20:27 +0300 Subject: [PATCH 0718/1122] testing chapter: added doc-testing examples --- src/SUMMARY.md | 1 + src/testing.md | 3 +- src/testing/doc_testing.md | 110 +++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/testing/doc_testing.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 57854579f8..56ab8fdaf0 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -186,6 +186,7 @@ - [Testing](testing.md) - [Unit testing](testing/unit_testing.md) + - [Documentation testing](testing/doc_testing.md) - [Meta](meta.md) - [Documentation](meta/doc.md) diff --git a/src/testing.md b/src/testing.md index ff8fe811f0..ddb0cd2e8b 100644 --- a/src/testing.md +++ b/src/testing.md @@ -6,7 +6,7 @@ includes support for writing software tests within the language itself. Testing comes in three "tastes": * [Unit][unit] testing. -* Doc testing. +* [Doc][doc] testing. * Integration testing. Also Rust has support for spectifying additional dependencies for tests: @@ -18,5 +18,6 @@ Also Rust has support for spectifying additional dependencies for tests: * [API Guidelines][doc-nursery] on doc-testing [unit]: ./testing/unit_testing.html +[doc]: ./testing/doc_testing.html [doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md new file mode 100644 index 0000000000..7e0d6f5367 --- /dev/null +++ b/src/testing/doc_testing.md @@ -0,0 +1,110 @@ +# Documentation testing + +The primary way of documenting a Rust project is through annotating the source +code. Documentation comments are writen in [markdown][markdown] and support code +blocks in them. Rust takes care about correctnes, so these code blocks are +compiled and used as tests. + +```rust,ignore +#![crate_name = "doccomments"] + +/// First line is a short summary describing function. +/// +/// The next lineas present detailed documentation. Code blocks start with +/// triple backquotes and have implicit `fn main()` inside +/// and `extern crate `. Assume we're testing `doccomments` crate: +/// +/// ``` +/// let result = doccomments::add(2, 3); +/// assert_eq!(result, 5); +/// ``` +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + +/// Usually doc comments may include sections Examples, Panics and Failures. +/// +/// The next function divides two numbers. +/// +/// # Examples +/// +/// ``` +/// let result = doccomments::div(10, 2); +/// assert_eq!(result, 5); +/// ``` +/// +/// # Panics +/// +/// The function panics if the second argument is zero. +/// +/// ```rust,should_panic +/// // panics on division by zero +/// doccomments::div(10, 0); +/// ``` +pub fn div(a: i32, b: i32) -> i32 { + if b == 0 { + panic!("Divide-by-zero error"); + } + a / b +} +``` + +Tests can be run with `cargo test`: + +```bash +$ cargo test +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests doccomments + +running 3 tests +test src/lib.rs - add (line 7) ... ok +test src/lib.rs - div (line 21) ... ok +test src/lib.rs - div (line 31) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +## Motivation behind documentation tests + +The main prupose of documentation tests is to serve as an examples that exercise +the functionality. One of the most important +[guidelines][question-instead-of-unwrap]. It allows using examples from docs as +a complete code snippets. But using `?` makes compilation fail since `main` +returns `unit`. The ability to hide some source lines from documentation comes +as a rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it and +`unwrap` it in hidden `main`. Sounds complicated? Here's an example: + +```rust,ignore +/// Using hidden `try_main` in doc tests. +/// +/// ``` +/// # // hidden lines start with `#` symbol, but they're still compileable! +/// # fn try_main() -> Result<(), String> { // line that wraps the body shown in doc +/// let res = try::try_div(10, 2)?; +/// # Ok(()) // returning from try_main +/// # } +/// # fn main() { // starting main that'll unwrap() +/// # try_main().unwrap(); // calling try_main and unwrapping +/// # // so that test'll panic in case of error +/// # } +pub fn try_div(a: i32, b: i32) -> Result { + if b == 0 { + Err(String::from("Divide-by-zero")) + } else { + Ok(a / b) + } +} +``` + +## See Also + +* [RFC505][RFC505] on documentation style +* [API Guidelines][doc-nursery] on documentation guidelines + +[doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html +[markdown]: https://daringfireball.net/projects/markdown/ +[RFC505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md +[question-instead-of-unwrap]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#examples-use--not-try-not-unwrap-c-question-mark From e4c78f298b368405a5ea0be9567d94dc8914f397 Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sat, 4 Nov 2017 14:00:11 +0300 Subject: [PATCH 0719/1122] testing chapter: added integration testing examples --- src/SUMMARY.md | 1 + src/testing.md | 3 +- src/testing/integration_testing.md | 88 ++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/testing/integration_testing.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 56ab8fdaf0..d2dbdaa97a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -187,6 +187,7 @@ - [Testing](testing.md) - [Unit testing](testing/unit_testing.md) - [Documentation testing](testing/doc_testing.md) + - [Integration testing](testing/integration_testing.md) - [Meta](meta.md) - [Documentation](meta/doc.md) diff --git a/src/testing.md b/src/testing.md index ddb0cd2e8b..6d2da4a2ad 100644 --- a/src/testing.md +++ b/src/testing.md @@ -7,7 +7,7 @@ Testing comes in three "tastes": * [Unit][unit] testing. * [Doc][doc] testing. -* Integration testing. +* [Integration][integration] testing. Also Rust has support for spectifying additional dependencies for tests: * Dev-dependencies. @@ -19,5 +19,6 @@ Also Rust has support for spectifying additional dependencies for tests: [unit]: ./testing/unit_testing.html [doc]: ./testing/doc_testing.html +[integration]: ./testing/integration_testing.html [doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md new file mode 100644 index 0000000000..a7f375ebb6 --- /dev/null +++ b/src/testing/integration_testing.md @@ -0,0 +1,88 @@ +# Integration testing + +[Unit tests][unit] are testing one module in isolation at a time: they're small +and can test private code. Integration tests are etxernal to your crate and use +only its public interface in the same way any other code would. Their purpose is +to test that many parts of your library work correctly together. + +Cargo looks for integration tests in `tests` directory next to `src`. + +File `src/lib.rs`: + +```rust,ignore +#![crate_name = "adder"] +// Assume that crate is called adder, will have to extern it in integration test. +pub fn add(a: i32, b: i32) -> i32 { + a + b +} +``` + +File with test: `tests/integration_test.rs`: + +```rust,ignore +// extern crate we're testing, same as any other code will do. +extern crate adder; + +#[test] +fn test_add() { + assert_eq!(adder::add(3, 2), 5); +} +``` + +Running tests with `cargo test` command: + +```bash +$ cargo test +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/integration_test-bcd60824f5fbfe19 + +running 1 test +test test_add ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +Each rust source file in `tests` directory is compiled as a separate crate. One +way of sharing some code between integration tests is making module with public +functions, importing and using it within tests. + +File `tests/common.rs`: + +```rust,ignore +pub fn setup() { + // some setup code, like creating required files/directories, starting + // servers, etc. +} +``` + +File with test: `tests/integration_test.rs` + +```rust,ignore +// extern crate we're testing, same as any other code will do. +extern crate adder; + +// importing common module. +mod common; + +#[test] +fn test_add() { + // using common code. + common::setup(); + assert_eq!(adder::add(3, 2), 5); +} +``` + +Modules with common code follow the ordinary [modules][mod] rules, so it's ok to +create common module as `tests/common/mod.rs`. + +[unit]: ./testing/unit_testing.html +[mod]: ./mod.html From 629271188011699b2b347b02593f8c4755ede02f Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sat, 4 Nov 2017 14:22:50 +0300 Subject: [PATCH 0720/1122] testing chapter: added dev-dependencies example --- src/SUMMARY.md | 1 + src/testing/dev_dependencies.md | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/testing/dev_dependencies.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d2dbdaa97a..889a9354a6 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -188,6 +188,7 @@ - [Unit testing](testing/unit_testing.md) - [Documentation testing](testing/doc_testing.md) - [Integration testing](testing/integration_testing.md) + - [Dev-dependencies](testing/dev_dependencies.md) - [Meta](meta.md) - [Documentation](meta/doc.md) diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md new file mode 100644 index 0000000000..0bc43c3004 --- /dev/null +++ b/src/testing/dev_dependencies.md @@ -0,0 +1,43 @@ +# Development dependencies + +Sometimes there is a need to have a dependency for tests (examples, benchmarks) +only. Such dependencies are added to `Cargo.toml` in `[dev-dependencies]` +section. These dependencies are not propagated to other packages which depend on +this package. + +One such example is some crate that extends standard `assert!` macros. +File `Cargo.toml`: + +```ignore +# crate data left out +[dev-dependencies] +pretty_assertions = "0.4.0" +``` + +File `src/lib.rs`: + +```rust,ignore +// externing crate for test-only use +#[cfg(test)] +#[macro_use] +extern crate pretty_assertions; + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_add() { + assert_eq!(add(2, 3), 5); + } +} +``` + +## See Also +[Cargo][cargo] docs on sepcifying dependencies. + +[cargo]: http://doc.crates.io/specifying-dependencies.html From 21226173199490f8c9bf85eabf22c99d34a56329 Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sat, 4 Nov 2017 14:25:06 +0300 Subject: [PATCH 0721/1122] testing chapter: added link to dev-dependencies subchapter --- src/testing.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/testing.md b/src/testing.md index 6d2da4a2ad..230448e32e 100644 --- a/src/testing.md +++ b/src/testing.md @@ -10,7 +10,7 @@ Testing comes in three "tastes": * [Integration][integration] testing. Also Rust has support for spectifying additional dependencies for tests: -* Dev-dependencies. +* [Dev-dependencies][dev-dependencies] ## See Also @@ -20,5 +20,6 @@ Also Rust has support for spectifying additional dependencies for tests: [unit]: ./testing/unit_testing.html [doc]: ./testing/doc_testing.html [integration]: ./testing/integration_testing.html +[dev-dependencies]: ./testing/dev_dependencies.html [doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html From 5d3251462a88a8cb3b08d04f63cea5fc6c5663df Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sat, 4 Nov 2017 14:28:37 +0300 Subject: [PATCH 0722/1122] testing: style --- src/testing/dev_dependencies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md index 0bc43c3004..cf6634f085 100644 --- a/src/testing/dev_dependencies.md +++ b/src/testing/dev_dependencies.md @@ -1,15 +1,15 @@ # Development dependencies -Sometimes there is a need to have a dependency for tests (examples, benchmarks) -only. Such dependencies are added to `Cargo.toml` in `[dev-dependencies]` -section. These dependencies are not propagated to other packages which depend on -this package. +Sometimes there is a need to have a dependencies for tests (examples, +benchmarks) only. Such dependencies are added to `Cargo.toml` in +`[dev-dependencies]` section. These dependencies are not propagated to other +packages which depend on this package. -One such example is some crate that extends standard `assert!` macros. +One such example is using a crate that extends standard `assert!` macros. File `Cargo.toml`: ```ignore -# crate data left out +# standard crate data is left out [dev-dependencies] pretty_assertions = "0.4.0" ``` From cbd202e4f22c2a2c3570d12b7df1aa7902a2b4db Mon Sep 17 00:00:00 2001 From: donpollo Date: Mon, 6 Nov 2017 17:01:37 +0100 Subject: [PATCH 0723/1122] Fix broken links in destructuring.md --- src/flow_control/match/destructuring.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index 6976afd4b0..fe60f81299 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -2,13 +2,13 @@ A `match` block can destructure items in a variety of ways. -* [Destructuring Enums](enum) -* [Destructuring Pointers](refs) -* [Destructuring Structutures](struct) -* [Destructuring Tuples](tuple) +* [Destructuring Enums][enum] +* [Destructuring Pointers][refs] +* [Destructuring Structutures][struct] +* [Destructuring Tuples][tuple] -[enum]: destructuring/destructure_enum.md -[refs]: destructuring/destructure_pointers.md -[struct]: destructuring/destructure_structures.md -[tuple]:destructuring/destructure_tuple.md +[enum]: /flow_control/match/destructuring/destructure_enum.html +[refs]: /flow_control/match/destructuring/destructure_pointers.html +[struct]: /flow_control/match/destructuring/destructure_structures.html +[tuple]: /flow_control/match/destructuring/destructure_tuple.html From 50a0bec2cca74f4f4ef8742141af23275cfec92b Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 11 Nov 2017 00:56:58 -0600 Subject: [PATCH 0724/1122] Still more snippet corrections --- src/cargo/test.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 8ef4bcca18..d17fb2f0e1 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -11,7 +11,7 @@ cargo test You should see output like this: -``` +```txt $ cargo test Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.89 secs @@ -32,7 +32,7 @@ You can also run tests whose name matches a pattern: cargo test test_foo ``` -``` +```txt $ cargo test test_foo Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.35 secs From dc249074806315c7ec3a15503eb9942a73a451a6 Mon Sep 17 00:00:00 2001 From: Aurelijus Banelis Date: Sat, 11 Nov 2017 13:01:03 +0200 Subject: [PATCH 0725/1122] Small typo fix --- src/macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.md b/src/macros.md index 8889d3f6a8..0b27fc9935 100644 --- a/src/macros.md +++ b/src/macros.md @@ -30,7 +30,7 @@ So why are macros useful? 1. Don't repeat yourself. There are many cases where you may need similar functionality in multiple places but with different types. Often, writing a - macro is a useful wait to avoid repeating code. (More on this later) + macro is a useful way to avoid repeating code. (More on this later) 2. Domain-specific languages. Macros allow you to define special syntax for a specific purpose. (More on this later) From 770ce892bd5b3295f318bcfb8de0be78a3c04c90 Mon Sep 17 00:00:00 2001 From: Fabio Correa Date: Sat, 18 Nov 2017 19:16:13 +0000 Subject: [PATCH 0726/1122] Mention to eprint! and eprintln! --- src/hello/print.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index 93357f732e..8f27487157 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -4,8 +4,10 @@ Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fm some of which include: * `format!`: write formatted text to [`String`][string] -* `print!`: same as `format!` but the text is printed to the console. +* `print!`: same as `format!` but the text is printed to the console (io::stdout). * `println!`: same as `print!` but a newline is appended. +* `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr). +* `eprintln!`: sames as `eprint!`but a newline is appended. All parse text in the same fashion. A plus is that the formatting correctness will be checked at compile time. From 97a913a7df2f1421652c9ceaa92342b475b6f306 Mon Sep 17 00:00:00 2001 From: Dhoi Almeida <26941289+dhoialmeida@users.noreply.github.com> Date: Sun, 19 Nov 2017 17:51:54 -0200 Subject: [PATCH 0727/1122] Update "dynamic_dispatch" link --- src/error/multiple_error_types/boxing_errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index 6257adaff3..c5f43a9332 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -67,6 +67,6 @@ fn main() { [Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] [box]: https://doc.rust-lang.org/std/boxed/struct.Box.html -[dynamic_dispatch]: https://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch +[dynamic_dispatch]: https://doc.rust-lang.org/book/second-edition/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch [error]: https://doc.rust-lang.org/std/error/trait.Error.html [from]: https://doc.rust-lang.org/std/convert/trait.From.html From 359f0cd95fc21003a3bf698129c6887fd50f9885 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 20 Nov 2017 07:58:59 -0500 Subject: [PATCH 0728/1122] fix formatting of examples in for --- src/flow_control/for.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index bfab6e91d2..b19aa34dd4 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -44,12 +44,12 @@ collection. ```rust, editable let names = vec!["Bob", "Frank", "Ferris"]; - for name in names.iter() { - match name { - &"Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), - } +for name in names.iter() { + match name { + &"Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), } +} ``` * `into_iter` - This consumes the collection so that on each iteration the exact @@ -60,11 +60,11 @@ let names = vec!["Bob", "Frank", "Ferris"]; let names = vec!["Bob", "Frank", "Ferris"]; for name in names.into_iter() { - match name { - "Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), - } + match name { + "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), } +} ``` * `iter_mut` - This mutably borrows each element of the collection, allowing for @@ -74,11 +74,11 @@ for name in names.into_iter() { let mut names = vec!["Bob", "Frank", "Ferris"]; for name in names.iter_mut() { - match name { - &mut "Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), - } + match name { + &mut "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), } +} ``` In the above snippets note the type of `match` branch, that is the key From 81080dc80f2ebd9ff6260895d721a59c8e7c2ce8 Mon Sep 17 00:00:00 2001 From: Angelo Lakra Date: Wed, 22 Nov 2017 12:44:52 -0700 Subject: [PATCH 0729/1122] Fixing spelling --- src/flow_control/match/destructuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index fe60f81299..a13f361004 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -4,7 +4,7 @@ A `match` block can destructure items in a variety of ways. * [Destructuring Enums][enum] * [Destructuring Pointers][refs] -* [Destructuring Structutures][struct] +* [Destructuring Structures][struct] * [Destructuring Tuples][tuple] From 5ae8ae2f7c5008874b9cd5ed64746cc55872c8be Mon Sep 17 00:00:00 2001 From: projektir Date: Wed, 22 Nov 2017 22:05:59 -0800 Subject: [PATCH 0730/1122] Adding license header to deploy.sh --- deploy.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/deploy.sh b/deploy.sh index 358ba9a37e..2c9c6a26fc 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,3 +1,13 @@ +# Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + #!/bin/bash rev=$(git rev-parse --short HEAD) From f4faec0240bd701c4daff48aa687fff0340eed06 Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sun, 26 Nov 2017 18:12:18 +0300 Subject: [PATCH 0731/1122] testing: style fixes as suggested in PR --- src/testing.md | 5 +++-- src/testing/doc_testing.md | 17 ++++++++--------- src/testing/integration_testing.md | 3 +-- src/testing/unit_testing.md | 15 +++++++-------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/testing.md b/src/testing.md index 230448e32e..bfb8e7b330 100644 --- a/src/testing.md +++ b/src/testing.md @@ -3,13 +3,14 @@ Rust is a programming language that cares a lot about correctness and it includes support for writing software tests within the language itself. -Testing comes in three "tastes": +Testing comes in three styles: * [Unit][unit] testing. * [Doc][doc] testing. * [Integration][integration] testing. -Also Rust has support for spectifying additional dependencies for tests: +Also Rust has support for specifying additional dependencies for tests: + * [Dev-dependencies][dev-dependencies] ## See Also diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index 7e0d6f5367..fcd79acef8 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -1,16 +1,14 @@ # Documentation testing The primary way of documenting a Rust project is through annotating the source -code. Documentation comments are writen in [markdown][markdown] and support code -blocks in them. Rust takes care about correctnes, so these code blocks are +code. Documentation comments are written in [markdown][markdown] and support code +blocks in them. Rust takes care about correctness, so these code blocks are compiled and used as tests. ```rust,ignore -#![crate_name = "doccomments"] - /// First line is a short summary describing function. /// -/// The next lineas present detailed documentation. Code blocks start with +/// The next lines present detailed documentation. Code blocks start with /// triple backquotes and have implicit `fn main()` inside /// and `extern crate `. Assume we're testing `doccomments` crate: /// @@ -22,7 +20,7 @@ pub fn add(a: i32, b: i32) -> i32 { a + b } -/// Usually doc comments may include sections Examples, Panics and Failures. +/// Usually doc comments may include sections "Examples", "Panics" and "Failures". /// /// The next function divides two numbers. /// @@ -45,6 +43,7 @@ pub fn div(a: i32, b: i32) -> i32 { if b == 0 { panic!("Divide-by-zero error"); } + a / b } ``` @@ -70,11 +69,11 @@ test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Motivation behind documentation tests The main prupose of documentation tests is to serve as an examples that exercise -the functionality. One of the most important +the functionality, which is one of the most important [guidelines][question-instead-of-unwrap]. It allows using examples from docs as -a complete code snippets. But using `?` makes compilation fail since `main` +complete code snippets. But using `?` makes compilation fail since `main` returns `unit`. The ability to hide some source lines from documentation comes -as a rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it and +to the rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it and `unwrap` it in hidden `main`. Sounds complicated? Here's an example: ```rust,ignore diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index a7f375ebb6..e2751154c8 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -10,7 +10,6 @@ Cargo looks for integration tests in `tests` directory next to `src`. File `src/lib.rs`: ```rust,ignore -#![crate_name = "adder"] // Assume that crate is called adder, will have to extern it in integration test. pub fn add(a: i32, b: i32) -> i32 { a + b @@ -20,7 +19,7 @@ pub fn add(a: i32, b: i32) -> i32 { File with test: `tests/integration_test.rs`: ```rust,ignore -// extern crate we're testing, same as any other code will do. +// extern crate we're testing, same as any other code would do. extern crate adder; #[test] diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index 7b471c88b1..e3914b221c 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -5,9 +5,8 @@ the expected manner. The bodies of test functions typically perform some setup, run the code we want to test, then assert whether the results are what we expect. -Typical scenario for grouping tests - adding `tests` [mod][mod] under with -[attribute][attribute] `#[cfg(test)]`. Test functions are marked with `#[test]` -attribute. +Most unit tests go into a `tests` [mod][mod] with the `#[cfg(test)]` [attribute][attribute]. +Test functions are marked with the `#[test]` attribute. Tests fail when something in the test function [panics][panic]. There are some helper [macros][macros]: @@ -30,7 +29,7 @@ fn bad_add(a: i32, b: i32) -> i32 { #[cfg(test)] mod tests { - // Note as useful idiom: importing names from outer (for mod tests) scope. + // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; #[test] @@ -75,8 +74,8 @@ test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out To check functions that should panic under certain circumstances, use attribute `#[should_panic]`. This attribute accepts optional parameter `expected = ` with -text of panic message: it helps making checks if function may panic in multiple -ways. +the text of the panic message. If your function can panic in multiple ways, it helps +make sure your test is testing the correct panic. ```rust,ignore pub fn divide_non_zero_result(a: u32, b: u32) -> u32 { @@ -132,7 +131,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Running specific tests -To run specific tests one may specify test name to `cargo test` command. +To run specific tests one may specify the test name to `cargo test` command. ```bash $ cargo test test_any_panic @@ -168,7 +167,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Ignoring tests -Tests can be marked with `#[ignore]` attribute to exclude some tests. Or to run +Tests can be marked with the`#[ignore]` attribute to exclude some tests. Or to run them with command `cargo test -- --ignored` ```rust From f0a2f5569c5844dc8be86d31cf2ea0351bd0e4dc Mon Sep 17 00:00:00 2001 From: Sergey Elantsev Date: Sun, 26 Nov 2017 18:16:01 +0300 Subject: [PATCH 0732/1122] testing: more spelling fixes --- src/testing/dev_dependencies.md | 2 +- src/testing/doc_testing.md | 4 ++-- src/testing/integration_testing.md | 2 +- src/testing/unit_testing.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md index cf6634f085..b6302a90fb 100644 --- a/src/testing/dev_dependencies.md +++ b/src/testing/dev_dependencies.md @@ -38,6 +38,6 @@ mod tests { ``` ## See Also -[Cargo][cargo] docs on sepcifying dependencies. +[Cargo][cargo] docs on specifying dependencies. [cargo]: http://doc.crates.io/specifying-dependencies.html diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index fcd79acef8..b21a0f96ee 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -68,7 +68,7 @@ test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Motivation behind documentation tests -The main prupose of documentation tests is to serve as an examples that exercise +The main purpose of documentation tests is to serve as an examples that exercise the functionality, which is one of the most important [guidelines][question-instead-of-unwrap]. It allows using examples from docs as complete code snippets. But using `?` makes compilation fail since `main` @@ -87,7 +87,7 @@ to the rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it a /// # } /// # fn main() { // starting main that'll unwrap() /// # try_main().unwrap(); // calling try_main and unwrapping -/// # // so that test'll panic in case of error +/// # // so that test will panic in case of error /// # } pub fn try_div(a: i32, b: i32) -> Result { if b == 0 { diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index e2751154c8..1f8b979731 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -1,7 +1,7 @@ # Integration testing [Unit tests][unit] are testing one module in isolation at a time: they're small -and can test private code. Integration tests are etxernal to your crate and use +and can test private code. Integration tests are external to your crate and use only its public interface in the same way any other code would. Their purpose is to test that many parts of your library work correctly together. diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index e3914b221c..43d1dc1310 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -11,7 +11,7 @@ Test functions are marked with the `#[test]` attribute. Tests fail when something in the test function [panics][panic]. There are some helper [macros][macros]: -* `assert!(expession)` - panics if expression evaluates to `false`. +* `assert!(expression)` - panics if expression evaluates to `false`. * `assert_eq!(left, right)` and `assert_ne!(left, right)` - testing left and right expressions for equality and inequality respectively. From 33b053f017b664e60501e9d499ed6ccb2db74ec9 Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Mon, 27 Nov 2017 22:21:24 -0500 Subject: [PATCH 0733/1122] Make structs style consistent struct Person definition should match the rest --- src/custom_types/structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 3c99f6dcde..6ade5e844a 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -11,7 +11,7 @@ There are three types of structures ("structs") that can be created using the #[derive(Debug)] struct Person<'a> { name: &'a str, - age: u8 + age: u8, } // A unit struct From ca4096c6f2e44609f3c11c8412c137fb9321457b Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Mon, 27 Nov 2017 22:32:38 -0500 Subject: [PATCH 0734/1122] Fix up extra space in enum example --- src/custom_types/enum.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index c48daba01b..93001a7616 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -27,7 +27,7 @@ enum WebEvent { // returns nothing. fn inspect(event: WebEvent) { match event { - WebEvent::PageLoad => println!("page loaded"), + WebEvent::PageLoad => println!("page loaded"), WebEvent::PageUnload => println!("page unloaded"), // Destructure `c` from inside the `enum`. WebEvent::KeyPress(c) => println!("pressed '{}'.", c), From 06ffdf1fd489ce447ac1676995670b0f89e211fc Mon Sep 17 00:00:00 2001 From: iabotsiTC <33929623+iabotsiTC@users.noreply.github.com> Date: Wed, 29 Nov 2017 16:57:14 +0100 Subject: [PATCH 0735/1122] Fixing typo --- src/crates/link.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crates/link.md b/src/crates/link.md index b5ab01d999..6bd17ae988 100644 --- a/src/crates/link.md +++ b/src/crates/link.md @@ -20,7 +20,7 @@ fn main() { ``` ```bash -# Where library.rlib is the path to to the compiled library, assumed that it's +# Where library.rlib is the path to the compiled library, assumed that it's # in the same directory here: $ rustc executable.rs --extern rary=library.rlib && ./executable called rary's `public_function()` From aef9dc86f0ffb3bee60aca3641bea3f2ffb18c20 Mon Sep 17 00:00:00 2001 From: projektir Date: Thu, 30 Nov 2017 23:21:48 -0800 Subject: [PATCH 0736/1122] Ignoring `process.md` as it requires `rustc` to be present in PATH --- src/std_misc/process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_misc/process.md b/src/std_misc/process.md index 0f9279f86d..9c9423090b 100644 --- a/src/std_misc/process.md +++ b/src/std_misc/process.md @@ -3,7 +3,7 @@ The `process::Output` struct represents the output of a finished child process, and the `process::Command` struct is a process builder. -```rust,editable +```rust,editable,ignore use std::process::Command; fn main() { From 1a2c006cb2bcdc835da68a67ba30b426aceb535a Mon Sep 17 00:00:00 2001 From: Huntr0 Date: Sun, 3 Dec 2017 21:57:28 +0100 Subject: [PATCH 0737/1122] c_like: Fix broken link The link to the `cast` page isn't working anymore because in commit a005ceddb37bcc6773145534c86a89e6b99f00cb the `cast.md` file has been moved into `types` dir and the link wasn't updated. --- src/custom_types/enum/c_like.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum/c_like.md b/src/custom_types/enum/c_like.md index f5e008aef7..bb5e3af315 100644 --- a/src/custom_types/enum/c_like.md +++ b/src/custom_types/enum/c_like.md @@ -34,4 +34,4 @@ fn main() { [casting][cast] -[cast]: /cast.html +[cast]: /types/cast.html From c2ea3ce1b3664fb819e0715f7b9c85ed9c0037e1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 4 Dec 2017 10:20:51 -0500 Subject: [PATCH 0738/1122] Zero doesn't exist anymore. --- src/trait/derive.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/trait/derive.md b/src/trait/derive.md index b254e3c896..c089170df6 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -11,7 +11,6 @@ The following is a list of derivable traits: * [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics' * [`Hash`][hash], to compute a hash from `&T`. * [`Default`][default], to create an empty instance of a data type. -* `Zero`, to create a zero instance of a numeric data type. * [`Debug`][debug], to format a value using the `{:?}` formatter. ```rust,example From e063596dfdb6215531686ef6652e8d9098b5bb5d Mon Sep 17 00:00:00 2001 From: feph Date: Wed, 6 Dec 2017 14:36:53 +0100 Subject: [PATCH 0739/1122] Minor change in activity for fmt::Display A generic solution for an output format like 3.3 + 7.2i is not achievable without a conditional(?) and, IMHO can't be solved by std::fmt alone. Changing the expected output to "3.3 +7.2i" (removing a whitespace) makes this easier, because it's simply the result of using "{real} {imag:+}i" as format string. --- src/hello/print/print_display.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 264b6d5e95..873bc3c44b 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -111,7 +111,7 @@ After checking the output of the above example, use the `Point2D` struct as guide to add a Complex struct to the example. When printed in the same way, the output should be: ``` -Display: 3.3 + 7.2i +Display: 3.3 +7.2i Debug: Complex { real: 3.3, imag: 7.2 } ``` From c82236935132ba80af007c3835412c45a68b9212 Mon Sep 17 00:00:00 2001 From: Jan Solanti Date: Mon, 30 Oct 2017 20:31:53 +0200 Subject: [PATCH 0740/1122] Add rule of thumb for error handling --- src/error.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/error.md b/src/error.md index d51e13f1d6..ee81f7ca00 100644 --- a/src/error.md +++ b/src/error.md @@ -5,6 +5,26 @@ example, failing to read a file and then continuing to use that *bad* input would clearly be problematic. Noticing and explicitly managing those errors saves the rest of the program from various pitfalls. +There are various ways to deal with errors in Rust, which are described in the +following subchapters. They all have more or less subtle differences and different +use cases. As a rule of thumb: + +An explicit `panic` is mainly useful for tests and dealing with unrecoverable errors. +For prototyping it can be useful, for example when dealing with functions that +haven't been implemented yet, but in those cases the more descriptive `unimplemented` +is better. In tests `panic` is a reasonable way to explicitly fail. + +The `Option` type is for when a value is optional or when the lack of a value is +not an error condition. For example the parent of a directory - `/` and `C:` don't +have one. When dealing with `Option`s, `unwrap` is fine for prototyping and cases +where it's absolutely certain that there is guaranteed to be a value. However `expect` +is more useful since it lets you specify an error message in case something goes +wrong anyway. + +When there is a chance that things do go wrong and the caller has to deal with the +problem, use `Result`. You can `unwrap` and `expect` them as well (please don't +do that unless it's a test or quick prototype). + For a more rigorous discussion of error handling, refer to the error handling section in the [official book][book]. From f21e365c931f8a769778ed650f6552fd397e1631 Mon Sep 17 00:00:00 2001 From: Mikhail Hogrefe Date: Sat, 9 Dec 2017 14:04:58 -0500 Subject: [PATCH 0741/1122] =?UTF-8?q?"enconding"=20=E2=86=92=20"encoding"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index 770b42a370..a771d0613a 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -155,7 +155,7 @@ fn main() { } ``` -For conversions between character encodings check out the [enconding][encoding-crate] crate. +For conversions between character encodings check out the [encoding][encoding-crate] crate. A more detailed listing of the ways to write string literals and escape characters is given in the ['Tokens' chapter][tokens] of the Rust Reference. From 1c053c6acab2c45f2b9bbf8394ab2e474438aad9 Mon Sep 17 00:00:00 2001 From: Michael Bryan Date: Mon, 11 Dec 2017 17:25:19 +1100 Subject: [PATCH 0742/1122] Fixed a typo --- src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index de7e6f6ee7..1ae9d79286 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -130,7 +130,7 @@ - [Clone](trait/clone.md) - [macro_rules!](macros.md) - - [Syntax](macro/syntax.md) + - [Syntax](macros/syntax.md) - [Designators](macros/designators.md) - [Overload](macros/overload.md) - [Repeat](macros/repeat.md) From bb1bace08e64395090b74835d2bc7d59c2f01a6e Mon Sep 17 00:00:00 2001 From: mark Date: Sun, 17 Dec 2017 23:30:39 -0600 Subject: [PATCH 0743/1122] Add to cargo chapter about top-level directory conventions --- src/SUMMARY.md | 1 + src/cargo/conventions.md | 36 ++++++++++++++++++++++++++++++++++++ src/cargo/test.md | 23 +++++++++++++++++++++-- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/cargo/conventions.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 118b0bcb10..7b07e9f3b0 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -84,6 +84,7 @@ - [Cargo](cargo.md) - [Dependencies](cargo/deps.md) + - [Conventions](cargo/conventions.md) - [Tests](cargo/test.md) - [Attributes](attribute.md) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md new file mode 100644 index 0000000000..ae7cab0d83 --- /dev/null +++ b/src/cargo/conventions.md @@ -0,0 +1,36 @@ +# Conventions + +In the previous chapter, we saw the following directory heirarcy: + +```txt +foo +├── Cargo.toml +└── src + └── main.rs +``` + +Suppose that we wanted to have two binaries in the same project, though. What +then? + +It turns out that cargo supports this. The default binary name is `main.rs`, as +we saw before, but you can add additional binaries by placing them in a `bin/` +directory: + +```txt +foo +├── Cargo.toml +└── src + ├── main.rs + └── bin + └── my_other_bin.rs +``` + +To tell cargo to compile or run this binary as opposed to the default or other +binaries, we just pass cargo the `--bin my_other_bin` flag, where `my_other_bin` +is the name of the binary we want to work with. + +In addition to extra binaries, there is support for benchmarks, tests, and +examples. The full capaibilities are documented +[here](http://doc.crates.io/book/guide/project-layout.html). + +In the next chapter, we will look more closely at tests. diff --git a/src/cargo/test.md b/src/cargo/test.md index d17fb2f0e1..9d31f8654e 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -2,8 +2,27 @@ As we know testing is integral to any piece of software! Rust has first-class support for unit and integration testing ([see that chapter for -more](https://rustbyexample.com/meta/test.html)). `cargo` naturally provides an -easy way to run all of your tests! +more](https://rustbyexample.com/meta/test.html); or [this +chapter](https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html) in +TRPL). + +From the testing chapters linked above, we see how to write unit tests and +integration tests. Organizationally, we can place unit tests in the modules they +test and integration tests in their own `tests/` directory: + +```txt +foo +├── Cargo.toml +├── src +│ └── main.rs +└── tests + ├── my_test.rs + └── my_other_test.rs +``` + +Each file in `tests` is a separate integration test. + +`cargo` naturally provides an easy way to run all of your tests! ```sh cargo test From 6c19fefe1486dc58c122987e0a0cf15a9e39405e Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Thu, 21 Dec 2017 00:21:21 -0500 Subject: [PATCH 0744/1122] Update book.toml This specifies the new mdBook syntax (properties under `[book]` table). It also adds the `editor = "ace"` config, which will fix #963. Once https://github.com/rust-lang-nursery/mdBook/pull/515 is merged, this won't be necessary. --- book.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/book.toml b/book.toml index af3ded6d77..60770d4eee 100644 --- a/book.toml +++ b/book.toml @@ -1,6 +1,8 @@ +[book] title = "Rust By Example" description = "A description" author = "The Rust Community" [output.html.playpen] editable = true +editor = "ace" From 3fafb615639f988c013dcd46563624416e7464c0 Mon Sep 17 00:00:00 2001 From: Fabio Correa Date: Sun, 24 Dec 2017 08:18:07 -0200 Subject: [PATCH 0745/1122] Fix on small typo --- src/attribute/crate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attribute/crate.md b/src/attribute/crate.md index c8a119a8e6..33674faaec 100644 --- a/src/attribute/crate.md +++ b/src/attribute/crate.md @@ -7,7 +7,7 @@ attribute can be used to set the name of the crate. However, it is important to note that both the `crate_type` and `crate_name` attributes have **no** effect whatsoever when using Cargo, the Rust package manager. Since Cargo is used for the majority of Rust projects, this means -real-world uses of `crate-type` and `crate_name` are relatively limited. +real-world uses of `crate_type` and `crate_name` are relatively limited. ```rust,editable // This crate is a library From b5c7fb134379bd98ef042cc1329d3dff8bdd44bf Mon Sep 17 00:00:00 2001 From: Fabio Correa Date: Sun, 24 Dec 2017 08:19:48 -0200 Subject: [PATCH 0746/1122] Correlation between imperative and functional examples Changes on variable name of the closures used in the functional example, only to allow easy correlation with the imperative example; for those not used to functional way. --- src/fn/hof.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fn/hof.md b/src/fn/hof.md index c5c28c45bd..568c79d413 100644 --- a/src/fn/hof.md +++ b/src/fn/hof.md @@ -33,10 +33,10 @@ fn main() { // Functional approach let sum_of_squared_odd_numbers: u32 = - (0..).map(|n| n * n) // All natural numbers squared - .take_while(|&n| n < upper) // Below upper limit - .filter(|&n| is_odd(n)) // That are odd - .fold(0, |sum, i| sum + i); // Sum them + (0..).map(|n| n * n) // All natural numbers squared + .take_while(|&n_squared| n_squared < upper) // Below upper limit + .filter(|&n_squared| is_odd(n_squared)) // That are odd + .fold(0, |acc, n_squared| acc + n_squared); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); } ``` From cf0e5e85b00b6cc586fab6ca3c551f3962fa98f9 Mon Sep 17 00:00:00 2001 From: Stefano Probst Date: Mon, 25 Dec 2017 18:44:08 +0100 Subject: [PATCH 0747/1122] Fix dead link in "aliases for Result" Dead link because folder was renamed. Maybe caused by a005ceddb37bcc6773145534c86a89e6b99f00cb. --- src/error/result/result_alias.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md index 50a38eaf52..7f376b24ea 100644 --- a/src/error/result/result_alias.md +++ b/src/error/result/result_alias.md @@ -42,5 +42,5 @@ fn main() { [`io::Result`][io_result] -[typealias]: /cast/alias.html +[typealias]: /types/alias.html [io_result]: https://doc.rust-lang.org/std/io/type.Result.html From d26913910927bb7dc9975fd9f4e4a89ec75f1156 Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Sat, 30 Dec 2017 17:04:18 -0500 Subject: [PATCH 0748/1122] updating word small fix --- src/flow_control/loop/return.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/loop/return.md b/src/flow_control/loop/return.md index 866eecf98b..8511b1e869 100644 --- a/src/flow_control/loop/return.md +++ b/src/flow_control/loop/return.md @@ -1,6 +1,6 @@ # Returning from loops -One of the uses of a `loop` is to retry an operation until it succeded. If the +One of the uses of a `loop` is to retry an operation until it succeeds. If the operation returns a value though, you might need to pass it to the rest of the code: put it after the `break`, and it will be returned by the `loop` expression. @@ -19,4 +19,4 @@ fn main() { assert_eq!(result, 20); } -``` \ No newline at end of file +``` From a7b837e4f0d99cc10c681b65df90355aee93357b Mon Sep 17 00:00:00 2001 From: Pramod Bisht Date: Tue, 9 Jan 2018 12:22:20 +0530 Subject: [PATCH 0749/1122] Fixed typos --- src/scope/raii.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/raii.md b/src/scope/raii.md index 42413c4813..66f22fe3c8 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -69,7 +69,7 @@ required to be implemented for every type, only implement it for your type if you require its own destructor logic. Run the below example to see how the [`Drop`] trait works. When the variable in -the `main` function goes out of scope the custom destructor wil be invoked. +the `main` function goes out of scope the custom destructor will be invoked. ```rust,editable struct ToDrop; From 0e35260d8cc5d7558165f395a1f80e7b8e005235 Mon Sep 17 00:00:00 2001 From: Wouter Date: Wed, 10 Jan 2018 22:39:49 +0100 Subject: [PATCH 0750/1122] Minor change in wording on if let page --- src/flow_control/if_let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index d94b961a1f..e0edd5aa09 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -1,6 +1,6 @@ # if let -For some use cases, `match` is awkward. For example: +For some use cases, when matching enums, `match` is awkward. For example: ```rust // Make `optional` of type `Option` From 108b5d8d1f790fd289e7eb2dabd3ae31235cef82 Mon Sep 17 00:00:00 2001 From: Havvy Date: Wed, 10 Jan 2018 22:15:22 -0800 Subject: [PATCH 0751/1122] Change links from '/foo.html' to 'foo.html' With mdbook, relative links in any document are relative to the top level of the book, so there's no need to start them with '/'s. There were also incorrect links in macros/syntax.md because of this - they have been fixed. There were also incorrect links to the stable Reference. These have also been updated. I did not change the doc.rlo links, as even though they could have been made relative for when RBE is on doc.rlo, we're still going to keep RBE.com's rendering up until RBE renders on stable docs, which is going to be awhile. But when RBE.com is just a redirect, they should be changed to "../std/MOAR" and "../book/MOAR" and "../reference/MOAR" as appropriate too. --- src/attribute.md | 4 ++-- src/attribute/cfg.md | 2 +- src/crates/lib.md | 2 +- src/custom_types/constants.md | 2 +- src/custom_types/enum.md | 8 ++++---- src/custom_types/enum/c_like.md | 2 +- src/custom_types/enum/enum_use.md | 4 ++-- src/custom_types/enum/testcase_linked_list.md | 4 ++-- src/custom_types/structs.md | 4 ++-- src/error/multiple_error_types/option_result.md | 2 +- .../reenter_question_mark.md | 2 +- src/error/multiple_error_types/wrap_error.md | 4 ++-- src/error/option_unwrap/and_then.md | 2 +- src/error/option_unwrap/map.md | 2 +- src/error/result/enter_question_mark.md | 2 +- src/error/result/result_alias.md | 2 +- src/flow_control/for.md | 2 +- src/flow_control/if_let.md | 4 ++-- src/flow_control/match/binding.md | 4 ++-- src/flow_control/match/destructuring.md | 8 ++++---- src/flow_control/match/guard.md | 2 +- src/flow_control/while_let.md | 4 ++-- src/fn/closures/anonymity.md | 2 +- src/fn/closures/capture.md | 2 +- src/fn/closures/output_parameters.md | 4 ++-- src/generics.md | 2 +- src/generics/assoc_items/the_problem.md | 4 ++-- src/generics/bounds.md | 10 +++++----- src/generics/bounds/testcase_empty.md | 2 +- src/generics/gen_fn.md | 4 ++-- src/generics/gen_trait.md | 4 ++-- src/generics/impl.md | 6 +++--- src/generics/multi_bounds.md | 4 ++-- src/generics/new_types.md | 2 +- src/generics/phantom.md | 6 +++--- src/generics/phantom/testcase_units.md | 16 ++++++++-------- src/generics/where.md | 4 ++-- src/hello.md | 2 +- src/hello/comment.md | 2 +- src/hello/print.md | 8 ++++---- src/hello/print/print_debug.md | 4 ++-- src/hello/print/print_display.md | 10 +++++----- src/hello/print/print_display/testcase_list.md | 12 ++++++------ src/macros/syntax.md | 6 +++--- src/mod/split.md | 2 +- src/mod/struct_visibility.md | 4 ++-- src/primitives.md | 6 +++--- src/primitives/literals.md | 2 +- src/primitives/tuples.md | 2 +- src/scope/borrow/mut.md | 2 +- src/scope/lifetime/explicit.md | 10 +++++----- src/scope/lifetime/fn.md | 4 ++-- src/scope/lifetime/lifetime_bounds.md | 6 +++--- src/scope/lifetime/methods.md | 4 ++-- src/scope/lifetime/static_lifetime.md | 2 +- src/scope/lifetime/struct.md | 2 +- src/scope/move.md | 2 +- src/scope/raii.md | 2 +- src/std.md | 4 ++-- src/std_misc.md | 6 +++--- src/std_misc/fs.md | 2 +- src/trait/derive.md | 2 +- src/types/alias.md | 2 +- src/types/literals.md | 6 +++--- 64 files changed, 130 insertions(+), 130 deletions(-) diff --git a/src/attribute.md b/src/attribute.md index 3540b31ff1..d945dd9123 100644 --- a/src/attribute.md +++ b/src/attribute.md @@ -23,6 +23,6 @@ Attributes can take arguments with different syntaxes: * `#[attribute(key = "value")]` * `#[attribute(value)]` -[cfg]: /attribute/cfg.html -[crate]: /attribute/crate.html +[cfg]: attribute/cfg.html +[crate]: attribute/crate.html [lint]: https://en.wikipedia.org/wiki/Lint_%28software%29 diff --git a/src/attribute/cfg.md b/src/attribute/cfg.md index 55e0e6ecb9..e7b56559f2 100644 --- a/src/attribute/cfg.md +++ b/src/attribute/cfg.md @@ -37,5 +37,5 @@ fn main() { [the reference][ref], [`cfg!`][cfg], and [macros][macros]. [cfg]: https://doc.rust-lang.org/std/macro.cfg!.html -[macros]: /macros.html +[macros]: macros.html [ref]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation diff --git a/src/crates/lib.md b/src/crates/lib.md index 16e7128dbc..a46c50936f 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -28,4 +28,4 @@ Libraries get prefixed with "lib", and by default they get named after their crate file, but this default name can be overridden using the [`crate_name` attribute][crate-name]. -[crate-name]: /attribute/crate.html \ No newline at end of file +[crate-name]: attribute/crate.html \ No newline at end of file diff --git a/src/custom_types/constants.md b/src/custom_types/constants.md index 63cc7f00ef..1d1df092a9 100644 --- a/src/custom_types/constants.md +++ b/src/custom_types/constants.md @@ -43,4 +43,4 @@ fn main() { https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md), [`'static` lifetime][static] -[static]: /scope/lifetime/static_lifetime.html +[static]: scope/lifetime/static_lifetime.html diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index 93001a7616..c605dc988f 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -60,8 +60,8 @@ fn main() { [`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] -[attributes]: /attribute.html +[attributes]: attribute.html [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[match]: /flow_control/match.html -[fn]: /fn.html -[str]: /std/str.html +[match]: flow_control/match.html +[fn]: fn.html +[str]: std/str.html diff --git a/src/custom_types/enum/c_like.md b/src/custom_types/enum/c_like.md index bb5e3af315..9dbc37c270 100644 --- a/src/custom_types/enum/c_like.md +++ b/src/custom_types/enum/c_like.md @@ -34,4 +34,4 @@ fn main() { [casting][cast] -[cast]: /types/cast.html +[cast]: types/cast.html diff --git a/src/custom_types/enum/enum_use.md b/src/custom_types/enum/enum_use.md index bddf6ae722..01eb99cbc7 100644 --- a/src/custom_types/enum/enum_use.md +++ b/src/custom_types/enum/enum_use.md @@ -46,5 +46,5 @@ fn main() { [`match`][match] and [`use`][use] -[use]: /mod/use.html -[match]: /flow_control/match.html +[use]: mod/use.html +[match]: flow_control/match.html diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index 47fc3269b1..c678d62c97 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -75,5 +75,5 @@ fn main() { [`Box`][box] and [methods][methods] -[box]: /std/box.html -[methods]: /fn/methods.html +[box]: std/box.html +[methods]: fn/methods.html diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 6ade5e844a..1b201b2921 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -84,6 +84,6 @@ fn main() { [`attributes`][attributes] and [destructuring][destructuring] -[attributes]: /attribute.html +[attributes]: attribute.html [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[destructuring]: /flow_control/match/destructuring.html +[destructuring]: flow_control/match/destructuring.html diff --git a/src/error/multiple_error_types/option_result.md b/src/error/multiple_error_types/option_result.md index 23bec6ab6a..331b458189 100644 --- a/src/error/multiple_error_types/option_result.md +++ b/src/error/multiple_error_types/option_result.md @@ -55,4 +55,4 @@ fn main() { } ``` -[enter_question_mark]: /error/result/enter_question_mark.html +[enter_question_mark]: error/result/enter_question_mark.html diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index 4df124aa81..3cdbbac918 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -86,4 +86,4 @@ top level. [`From::from`][from] and [`?`][q_mark] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[q_mark]: https://doc.rust-lang.org/reference/expressions.html#the--operator +[q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the--operator diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index 074f23ee02..5dd8083aa2 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -91,5 +91,5 @@ plate for you. [`From::from`][from] and [`Enums`][enums] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[q_mark]: https://doc.rust-lang.org/reference/expressions.html#the--operator -[enums]: /custom_types/enum.html +[q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the--operator +[enums]: custom_types/enum.html diff --git a/src/error/option_unwrap/and_then.md b/src/error/option_unwrap/and_then.md index 3c927c6848..aab95cac30 100644 --- a/src/error/option_unwrap/and_then.md +++ b/src/error/option_unwrap/and_then.md @@ -71,6 +71,6 @@ fn main() { [closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] -[closures]: /fn/closures.html +[closures]: fn/closures.html [option]: https://doc.rust-lang.org/std/option/enum.Option.html [and_then]: https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/src/error/option_unwrap/map.md b/src/error/option_unwrap/map.md index b52dda8a3a..89b06cca90 100644 --- a/src/error/option_unwrap/map.md +++ b/src/error/option_unwrap/map.md @@ -81,6 +81,6 @@ fn main() { [closures][closures], [`Option`][option], [`Option::map()`][map] [combinators]: https://doc.rust-lang.org/book/glossary.html#combinators -[closures]: /fn/closures.html +[closures]: fn/closures.html [option]: https://doc.rust-lang.org/std/option/enum.Option.html [map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index e3f227fc2e..0a5c0722ff 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -69,4 +69,4 @@ fn main() { [^1]: See [re-enter ?][re_enter_?] for more details. -[re_enter_?]: /error/multiple_error_types/reenter_question_mark.html +[re_enter_?]: error/multiple_error_types/reenter_question_mark.html diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md index 7f376b24ea..c0466357b1 100644 --- a/src/error/result/result_alias.md +++ b/src/error/result/result_alias.md @@ -42,5 +42,5 @@ fn main() { [`io::Result`][io_result] -[typealias]: /types/alias.html +[typealias]: types/alias.html [io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/src/flow_control/for.md b/src/flow_control/for.md index b19aa34dd4..e6f219d7fc 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -89,4 +89,4 @@ implies differing actions that are able to be performed. [Iterator][iter] -[iter]: /trait/iter.html +[iter]: trait/iter.html diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index d94b961a1f..77fedb73fd 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -63,6 +63,6 @@ fn main() { [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] -[enum]: /custom_types/enum.html +[enum]: custom_types/enum.html [if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 -[option]: /std/option.html +[option]: std/option.html diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index 12c6341eda..dc6322bb92 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -27,6 +27,6 @@ fn main() { ``` ### See also: -[functions][functions] +[functions] -[functions]: /fn.html +[functions]: fn.html diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index a13f361004..ce59b15407 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -8,7 +8,7 @@ A `match` block can destructure items in a variety of ways. * [Destructuring Tuples][tuple] -[enum]: /flow_control/match/destructuring/destructure_enum.html -[refs]: /flow_control/match/destructuring/destructure_pointers.html -[struct]: /flow_control/match/destructuring/destructure_structures.html -[tuple]: /flow_control/match/destructuring/destructure_tuple.html +[enum]: flow_control/match/destructuring/destructure_enum.html +[refs]: flow_control/match/destructuring/destructure_pointers.html +[struct]: flow_control/match/destructuring/destructure_structures.html +[tuple]: flow_control/match/destructuring/destructure_tuple.html diff --git a/src/flow_control/match/guard.md b/src/flow_control/match/guard.md index 165306e190..e52c198e8f 100644 --- a/src/flow_control/match/guard.md +++ b/src/flow_control/match/guard.md @@ -20,4 +20,4 @@ fn main() { ### See also: -[Tuples](/primitives/tuples.html) +[Tuples](primitives/tuples.html) diff --git a/src/flow_control/while_let.md b/src/flow_control/while_let.md index 0f5fddc44c..5938de4ee4 100644 --- a/src/flow_control/while_let.md +++ b/src/flow_control/while_let.md @@ -57,6 +57,6 @@ fn main() { [`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] -[enum]: /custom_types/enum.html -[option]: /std/option.html +[enum]: custom_types/enum.html +[option]: std/option.html [while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 diff --git a/src/fn/closures/anonymity.md b/src/fn/closures/anonymity.md index d6881bc389..5e6840c9b4 100644 --- a/src/fn/closures/anonymity.md +++ b/src/fn/closures/anonymity.md @@ -49,7 +49,7 @@ fn main() { [A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] -[generics]: /generics.html +[generics]: generics.html [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index 361676acbe..df2ce02cba 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -73,5 +73,5 @@ fn main() { [`Box`][box] and [`std::mem::drop`][drop] -[box]: /std/box.html +[box]: std/box.html [drop]: https://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index b3fae31472..87fe26f6f3 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -46,8 +46,8 @@ fn main() { [Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. -[box]: /std/box.html +[box]: std/box.html [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html -[generics]: /generics.html +[generics]: generics.html diff --git a/src/generics.md b/src/generics.md index 9c3f97397d..641e0cf0ae 100644 --- a/src/generics.md +++ b/src/generics.md @@ -60,5 +60,5 @@ fn main() { [`struct`s][structs] -[structs]: /custom_types/structs.html +[structs]: custom_types/structs.html [camelcase]: https://en.wikipedia.org/wiki/CamelCase diff --git a/src/generics/assoc_items/the_problem.md b/src/generics/assoc_items/the_problem.md index 45cc3f62c4..e55c42fb2b 100644 --- a/src/generics/assoc_items/the_problem.md +++ b/src/generics/assoc_items/the_problem.md @@ -63,5 +63,5 @@ fn main() { [`struct`s][structs], and [`trait`s][traits] -[structs]: /custom_types/structs.html -[traits]: /trait.html +[structs]: custom_types/structs.html +[traits]: trait.html diff --git a/src/generics/bounds.md b/src/generics/bounds.md index f8d73e42df..dbe4e7fa04 100644 --- a/src/generics/bounds.md +++ b/src/generics/bounds.md @@ -74,8 +74,8 @@ some cases to be more expressive. [`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] -[fmt]: /hello/print.html -[methods]: /fn/methods.html -[structs]: /custom_types/structs.html -[traits]: /trait.html -[where]: /generics/where.html +[fmt]: hello/print.html +[methods]: fn/methods.html +[structs]: custom_types/structs.html +[traits]: trait.html +[where]: generics/where.html diff --git a/src/generics/bounds/testcase_empty.md b/src/generics/bounds/testcase_empty.md index 9f7102a6ac..9e0a850af8 100644 --- a/src/generics/bounds/testcase_empty.md +++ b/src/generics/bounds/testcase_empty.md @@ -40,4 +40,4 @@ fn main() { [eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html [ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html -[traits]: /trait.html +[traits]: trait.html diff --git a/src/generics/gen_fn.md b/src/generics/gen_fn.md index 7bbdbaae27..3c8b2f9528 100644 --- a/src/generics/gen_fn.md +++ b/src/generics/gen_fn.md @@ -55,5 +55,5 @@ fn main() { [functions][fn] and [`struct`s][structs] -[fn]: /fn.html -[structs]: /custom_types/structs.html +[fn]: fn.html +[structs]: custom_types/structs.html diff --git a/src/generics/gen_trait.md b/src/generics/gen_trait.md index 58360c02b4..adde475b42 100644 --- a/src/generics/gen_trait.md +++ b/src/generics/gen_trait.md @@ -41,5 +41,5 @@ fn main() { [`Drop`][Drop], [`struct`][structs], and [`trait`][traits] [Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html -[structs]: /custom_types/structs.html -[traits]: /trait.html +[structs]: custom_types/structs.html +[traits]: trait.html diff --git a/src/generics/impl.md b/src/generics/impl.md index 0362532731..f5b4c44fd9 100644 --- a/src/generics/impl.md +++ b/src/generics/impl.md @@ -46,7 +46,7 @@ fn main() { [functions returning references][fn], [`impl`][methods], and [`struct`][structs] -[fn]: /scope/lifetime/fn.html -[methods]: /fn/methods.html +[fn]: scope/lifetime/fn.html +[methods]: fn/methods.html [specialization_plans]: https://blog.rust-lang.org/2015/05/11/traits.html#the-future -[structs]: /custom_types/structs.html +[structs]: custom_types/structs.html diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md index d282c02d75..9c1dfb6680 100644 --- a/src/generics/multi_bounds.md +++ b/src/generics/multi_bounds.md @@ -33,5 +33,5 @@ fn main() { [`std::fmt`][fmt] and [`trait`s][traits] -[fmt]: /hello/print.html -[traits]: /trait.html +[fmt]: hello/print.html +[traits]: trait.html diff --git a/src/generics/new_types.md b/src/generics/new_types.md index 8d3cc3495b..2ac7dc7f63 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -47,5 +47,5 @@ Uncomment the last print statement to observe that the type supplied must be `Ye [`structs`][struct] -[struct]: /custom_types/structs.html +[struct]: custom_types/structs.html diff --git a/src/generics/phantom.md b/src/generics/phantom.md index 66a826bc4b..7e9d7f5f04 100644 --- a/src/generics/phantom.md +++ b/src/generics/phantom.md @@ -57,7 +57,7 @@ fn main() { [Derive], [struct], and [TupleStructs] -[Derive]: /trait/derive.html -[struct]: /custom_types/structs.html -[TupleStructs]: /custom_types/structs.html +[Derive]: trait/derive.html +[struct]: custom_types/structs.html +[TupleStructs]: custom_types/structs.html [std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/src/generics/phantom/testcase_units.md b/src/generics/phantom/testcase_units.md index 3df6504b6c..52480316f7 100644 --- a/src/generics/phantom/testcase_units.md +++ b/src/generics/phantom/testcase_units.md @@ -77,12 +77,12 @@ fn main() { [Borrowing (`&`)], [Bounds (`X: Y`)], [enum], [impl & self], [Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. -[Borrowing (`&`)]: /scope/borrow.html -[Bounds (`X: Y`)]: /generics/bounds.html -[enum]: /custom_types/enum.html -[impl & self]: /fn/methods.html -[Overloading]: /trait/ops.html -[ref]: /scope/borrow/ref.html -[Traits (`X for Y`)]: /trait.html -[TupleStructs]: /custom_types/structs.html +[Borrowing (`&`)]: scope/borrow.html +[Bounds (`X: Y`)]: generics/bounds.html +[enum]: custom_types/enum.html +[impl & self]: fn/methods.html +[Overloading]: trait/ops.html +[ref]: scope/borrow/ref.html +[Traits (`X for Y`)]: trait.html +[TupleStructs]: custom_types/structs.html [std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html diff --git a/src/generics/where.md b/src/generics/where.md index 483843350f..89da6de87c 100644 --- a/src/generics/where.md +++ b/src/generics/where.md @@ -50,6 +50,6 @@ fn main() { [RFC][where], [`struct`][struct], and [`trait`][trait] -[struct]: /custom_types/structs.html -[trait]: /trait.html +[struct]: custom_types/structs.html +[trait]: trait.html [where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md diff --git a/src/hello.md b/src/hello.md index 87df4027b4..a11e309a06 100644 --- a/src/hello.md +++ b/src/hello.md @@ -46,4 +46,4 @@ Hello World! I'm a Rustacean! ``` -[macros]: ./macros.html +[macros]: macros.html diff --git a/src/hello/comment.md b/src/hello/comment.md index f88d02fcf8..fc116c1650 100644 --- a/src/hello/comment.md +++ b/src/hello/comment.md @@ -48,4 +48,4 @@ fn main() { [Library documentation][docs] -[docs]: /meta/doc.html +[docs]: meta/doc.html diff --git a/src/hello/print.md b/src/hello/print.md index 8f27487157..e62da894f8 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -83,7 +83,7 @@ for these types. To print text for custom types, more steps are required. and [`traits`][traits] [fmt]: https://doc.rust-lang.org/std/fmt/ -[macros]: /macros.html -[string]: /std/str.html -[structs]: /custom_types/structs.html -[traits]: /trait.html +[macros]: macros.html +[string]: std/str.html +[structs]: custom_types/structs.html +[traits]: trait.html diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index 8a0e0e2045..4e68b7fadc 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -78,7 +78,7 @@ One can manually implement `fmt::Display` to control the display. and [`struct`][structs] [attributes]: https://doc.rust-lang.org/reference/attributes.html -[derive]: /trait/derive.html +[derive]: trait/derive.html [fmt]: https://doc.rust-lang.org/std/fmt/ -[structs]: /custom_types/structs.html +[structs]: custom_types/structs.html diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 873bc3c44b..90385aac66 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -120,9 +120,9 @@ Debug: Complex { real: 3.3, imag: 7.2 } [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] -[derive]: /trait/derive.html +[derive]: trait/derive.html [fmt]: https://doc.rust-lang.org/std/fmt/ -[macros]: /macros.html -[structs]: /custom_types/structs.html -[traits]: /trait.html -[use]: /mod/use.html +[macros]: macros.html +[structs]: custom_types/structs.html +[traits]: trait.html +[use]: mod/use.html diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index ee332d0f2c..94faa75cf0 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -71,9 +71,9 @@ Try changing the program so that the index of each element in the vector is also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], [`?`][q_mark], and [`vec!`][vec] -[for]: /flow_control/for.html -[result]: /std/result.html -[ref]: /scope/borrow/ref.html -[struct]: /custom_types/structs.html -[q_mark]: /std/result/question_mark.html -[vec]: /std/vec.html +[for]: flow_control/for.html +[result]: std/result.html +[ref]: scope/borrow/ref.html +[struct]: custom_types/structs.html +[q_mark]: std/result/question_mark.html +[vec]: std/vec.html diff --git a/src/macros/syntax.md b/src/macros/syntax.md index c318d9bd41..435d64e21d 100644 --- a/src/macros/syntax.md +++ b/src/macros/syntax.md @@ -3,6 +3,6 @@ In following subsections, we will show how to define macros in Rust. There are three basic ideas: -- [Patterns and Designators](designators.md) -- [Overloading](overload.md) -- [Repetition](repeat.md) +- [Patterns and Designators](macros/designators.md) +- [Overloading](macros/overload.md) +- [Repetition](macros/repeat.md) diff --git a/src/mod/split.md b/src/mod/split.md index 16e0a60e1b..703b915ae9 100644 --- a/src/mod/split.md +++ b/src/mod/split.md @@ -93,4 +93,4 @@ called `my::indirect_access()`, that called `my::nested::function()` ``` -[visibility]: /mod/visibility.html +[visibility]: mod/visibility.html diff --git a/src/mod/struct_visibility.md b/src/mod/struct_visibility.md index d365355374..e10c526e9a 100644 --- a/src/mod/struct_visibility.md +++ b/src/mod/struct_visibility.md @@ -55,5 +55,5 @@ fn main() { [generics][generics] and [methods][methods] -[generics]: /generics.html -[methods]: /fn/methods.html \ No newline at end of file +[generics]: generics.html +[methods]: fn/methods.html \ No newline at end of file diff --git a/src/primitives.md b/src/primitives.md index 36561fd78a..aa3e3ba18e 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -57,6 +57,6 @@ fn main() { [the `std` library][std], [`mut`][mut], [inference], and [shadowing] [std]: https://doc.rust-lang.org/std/ -[mut]: https://rustbyexample.com/variable_bindings/mut.html -[inference]: https://rustbyexample.com/cast/inference.html -[shadowing]: https://rustbyexample.com/variable_bindings/scope.html +[mut]: variable_bindings/mut.html +[inference]: types/inference.html +[shadowing]: variable_bindings/scope.html diff --git a/src/primitives/literals.md b/src/primitives/literals.md index 1f27ac4ee6..dee2be02f3 100644 --- a/src/primitives/literals.md +++ b/src/primitives/literals.md @@ -42,5 +42,5 @@ fn main() { } ``` -[rust op-prec]: https://doc.rust-lang.org/reference/expressions.html#operator-precedence +[rust op-prec]: https://doc.rust-lang.org/reference/expressions.html#expression-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index c8586db555..253aa6fc26 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -94,4 +94,4 @@ fn main() { ( 1.2 2.2 ) ``` -[print_display]: /hello/print/print_display.html +[print_display]: hello/print/print_display.html diff --git a/src/scope/borrow/mut.md b/src/scope/borrow/mut.md index 282154614e..e9082b135b 100644 --- a/src/scope/borrow/mut.md +++ b/src/scope/borrow/mut.md @@ -56,4 +56,4 @@ fn main() { ### See also: [`static`][static] -[static]: ../lifetime/static_lifetime.html +[static]: scope/lifetime/static_lifetime.html diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md index 57941f1b1b..89c1279183 100644 --- a/src/scope/lifetime/explicit.md +++ b/src/scope/lifetime/explicit.md @@ -63,13 +63,13 @@ fn main() { } ``` -[^1]: [elision][elision] implicitly annotates lifetimes and so is different. +[^1]: [elision] implicitly annotates lifetimes and so is different. ### See also: [generics][generics] and [closures][closures] -[anonymity]: /fn/closures/anonymity.html -[closures]: /fn/closures.html -[elision]: /scope/lifetime/elision.html -[generics]: /generics.html +[anonymity]: fn/closures/anonymity.html +[closures]: fn/closures.html +[elision]: scope/lifetime/elision.html +[generics]: generics.html diff --git a/src/scope/lifetime/fn.md b/src/scope/lifetime/fn.md index 8b061ab537..ee0c4e7857 100644 --- a/src/scope/lifetime/fn.md +++ b/src/scope/lifetime/fn.md @@ -59,5 +59,5 @@ fn main() { [functions][fn] -[elision]: /scope/lifetime/elision.html -[fn]: /fn.html +[elision]: scope/lifetime/elision.html +[fn]: fn.html diff --git a/src/scope/lifetime/lifetime_bounds.md b/src/scope/lifetime/lifetime_bounds.md index 17aff6c377..e3d0a438ad 100644 --- a/src/scope/lifetime/lifetime_bounds.md +++ b/src/scope/lifetime/lifetime_bounds.md @@ -48,6 +48,6 @@ fn main() { [generics][generics], [bounds in generics][bounds], and [multiple bounds in generics][multibounds] -[generics]: /generics.html -[bounds]: /generics/bounds.html -[multibounds]: /generics/multi_bounds.html \ No newline at end of file +[generics]: generics.html +[bounds]: generics/bounds.html +[multibounds]: generics/multi_bounds.html \ No newline at end of file diff --git a/src/scope/lifetime/methods.md b/src/scope/lifetime/methods.md index 8e1a508bbd..28588540ba 100644 --- a/src/scope/lifetime/methods.md +++ b/src/scope/lifetime/methods.md @@ -23,6 +23,6 @@ fn main() { ### See also: -[methods][methods] +[methods] -[methods]: /fn/methods.html \ No newline at end of file +[methods]: fn/methods.html \ No newline at end of file diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index dbf0082ce1..5f154dba17 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -49,4 +49,4 @@ fn main() { [`'static` constants][static_const] -[static_const]: /custom_types/constants.html \ No newline at end of file +[static_const]: custom_types/constants.html \ No newline at end of file diff --git a/src/scope/lifetime/struct.md b/src/scope/lifetime/struct.md index 39dc824675..2951bcc539 100644 --- a/src/scope/lifetime/struct.md +++ b/src/scope/lifetime/struct.md @@ -43,4 +43,4 @@ fn main() { [`structs`][structs] -[structs]: /custom_types/structs.html +[structs]: custom_types/structs.html diff --git a/src/scope/move.md b/src/scope/move.md index dd4085ac1d..84372af8f2 100644 --- a/src/scope/move.md +++ b/src/scope/move.md @@ -57,4 +57,4 @@ fn main() { } ``` -[references]: /flow_control/match/destructuring/destructure_pointers.html +[references]: flow_control/match/destructuring/destructure_pointers.html diff --git a/src/scope/raii.md b/src/scope/raii.md index 66f22fe3c8..d5c00a5b97 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -91,6 +91,6 @@ fn main() { [Box][box] [raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization -[box]: /std/box.html +[box]: std/box.html [valgrind]: http://valgrind.org/info/ [`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html diff --git a/src/std.md b/src/std.md index cea4704d82..debfc73f49 100644 --- a/src/std.md +++ b/src/std.md @@ -11,7 +11,7 @@ the `primitives`. Some of these include: ### See also: -[primitives][primitives] and [the std library][std] +[primitives] and [the std library][std] -[primitives]: /primitives.html +[primitives]: primitives.html [std]: https://doc.rust-lang.org/std/ diff --git a/src/std_misc.md b/src/std_misc.md index c170428bfe..5106b934de 100644 --- a/src/std_misc.md +++ b/src/std_misc.md @@ -7,11 +7,11 @@ things such as: * Channels * File I/O -These expand beyond what the [primitives][primitives] provide. +These expand beyond what the [primitives] provide. ### See also: -[primitives][primitives] and [the std library][std] +[primitives] and [the std library][std] -[primitives]: /primitives.html +[primitives]: primitives.html [std]: https://doc.rust-lang.org/std/ diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index f6444cd231..e41fbcdc8a 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -144,4 +144,4 @@ fn cat(path: &Path) -> io::Result { [`cfg!`][cfg] -[cfg]: /attribute/cfg.html +[cfg]: attribute/cfg.html diff --git a/src/trait/derive.md b/src/trait/derive.md index c089170df6..465eed2683 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -64,7 +64,7 @@ fn main() { ### See also: [`derive`][derive] -[attribute]: /attribute.html +[attribute]: attribute.html [eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html [partial-eq]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html [ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html diff --git a/src/types/alias.md b/src/types/alias.md index cad75c7bea..3c3bed0162 100644 --- a/src/types/alias.md +++ b/src/types/alias.md @@ -33,4 +33,4 @@ is an alias for the `Result` type. ### See also: -[Attributes](/attribute.html) \ No newline at end of file +[Attributes](attribute.html) \ No newline at end of file diff --git a/src/types/literals.md b/src/types/literals.md index cf33b6a0cb..db2b7323f2 100644 --- a/src/types/literals.md +++ b/src/types/literals.md @@ -38,6 +38,6 @@ yet, here's a brief explanation for the impatient readers: is defined in the `std` *crate*. For more details, see [modules][mod] and [crates][crate]. -[borrow]: /scope/borrow.html -[mod]: /mod.html -[crate]: /crates.html +[borrow]: scope/borrow.html +[mod]: mod.html +[crate]: crates.html From 0c3c7a9a2aba5b48367e364ef5969c755975472b Mon Sep 17 00:00:00 2001 From: Havvy Date: Thu, 11 Jan 2018 10:47:47 -0800 Subject: [PATCH 0752/1122] Change more links. For the rationale, see the previous commit. This one concerns itself with changes that happened since the previous commit was written. --- src/cargo/test.md | 2 +- src/testing.md | 8 ++++---- src/testing/doc_testing.md | 2 +- src/testing/integration_testing.md | 4 ++-- src/testing/unit_testing.md | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 9d31f8654e..4efc5ab100 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -2,7 +2,7 @@ As we know testing is integral to any piece of software! Rust has first-class support for unit and integration testing ([see that chapter for -more](https://rustbyexample.com/meta/test.html); or [this +more](meta/test.html); or [this chapter](https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html) in TRPL). diff --git a/src/testing.md b/src/testing.md index bfb8e7b330..24c7a24381 100644 --- a/src/testing.md +++ b/src/testing.md @@ -18,9 +18,9 @@ Also Rust has support for specifying additional dependencies for tests: * [The Book][doc-testing] chapter on testing * [API Guidelines][doc-nursery] on doc-testing -[unit]: ./testing/unit_testing.html -[doc]: ./testing/doc_testing.html -[integration]: ./testing/integration_testing.html -[dev-dependencies]: ./testing/dev_dependencies.html +[unit]: testing/unit_testing.html +[doc]: testing/doc_testing.html +[integration]: testing/integration_testing.html +[dev-dependencies]: testing/dev_dependencies.html [doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index b21a0f96ee..5246ecba9a 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -1,7 +1,7 @@ # Documentation testing The primary way of documenting a Rust project is through annotating the source -code. Documentation comments are written in [markdown][markdown] and support code +code. Documentation comments are written in [markdown] and support code blocks in them. Rust takes care about correctness, so these code blocks are compiled and used as tests. diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index 1f8b979731..1906b2b131 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -83,5 +83,5 @@ fn test_add() { Modules with common code follow the ordinary [modules][mod] rules, so it's ok to create common module as `tests/common/mod.rs`. -[unit]: ./testing/unit_testing.html -[mod]: ./mod.html +[unit]: testing/unit_testing.html +[mod]: mod.html diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index 43d1dc1310..252577f0ef 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -224,7 +224,7 @@ running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` -[attribute]: ../attribute.html -[panic]: ../std/panic.html -[macros]: ../macros.html -[mod]: ../mod.html +[attribute]: attribute.html +[panic]: std/panic.html +[macros]: macros.html +[mod]: mod.html From 19f16aff289d576f7f8d8e40a755f73d7164dff3 Mon Sep 17 00:00:00 2001 From: Wouter Date: Fri, 12 Jan 2018 13:04:31 +0100 Subject: [PATCH 0753/1122] Added if let example with custom enum --- src/flow_control/if_let.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index e0edd5aa09..bea14e2467 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -59,6 +59,41 @@ fn main() { } ``` +In the same way, `if let` can be used to match any enum value: + +```rust,editable +// Our example enum +enum Foo { + Bar, + Baz, + Qux(u32) +} + +fn main() { + // Create example variables + let a = Foo::Bar; + let b = Foo::Baz; + let c = Foo::Qux(100); + + // Variable a matches Foo::Bar + if let Foo::Bar = a { + println!("a is foobar"); + } + + // Variable b does not match Foo::Bar + // So this will print nothing + if let Foo::Bar = b { + println!("b is foobar"); + } + + // Variable c matches Foo::Qux which has a value + // Similar to Some() in the previous example + if let Foo::Qux(value) = c { + println!("c is {}", value); + } +} +``` + ### See also: [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] From ad324c2c6b1ba54dfee810374f61a4412c6127c5 Mon Sep 17 00:00:00 2001 From: projektir Date: Fri, 12 Jan 2018 17:47:03 -0800 Subject: [PATCH 0754/1122] Fixing links --- src/cargo/test.md | 3 +-- src/error/result/enter_question_mark.md | 4 ++-- .../match/destructuring/destructure_enum.md | 4 ++-- .../match/destructuring/destructure_structures.md | 2 +- .../match/destructuring/destructure_tuple.md | 2 +- src/macros/syntax.md | 10 +++++++--- src/std_misc/threads/testcase_mapreduce.md | 12 ++++++------ src/unsafe.md | 2 +- 8 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 4efc5ab100..933c6c5e4a 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -1,8 +1,7 @@ # Testing As we know testing is integral to any piece of software! Rust has first-class -support for unit and integration testing ([see that chapter for -more](meta/test.html); or [this +support for unit and integration testing ([see this chapter](https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html) in TRPL). diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index 0a5c0722ff..aa4627c2c3 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -9,7 +9,7 @@ Upon finding an `Err`, there are two valid actions to take: 1. `panic!` which we already decided to try to avoid if possible 2. `return` because an `Err` means it cannot be handled -`?` is *almost*[^1] exactly equivalent to an `unwrap` which `return`s +`?` is *almost*[^†] exactly equivalent to an `unwrap` which `return`s instead of `panic`s on `Err`s. Let's see how we can simplify the earlier example that used combinators: @@ -67,6 +67,6 @@ fn main() { ``` -[^1]: See [re-enter ?][re_enter_?] for more details. +[^†]: See [re-enter ?][re_enter_?] for more details. [re_enter_?]: error/multiple_error_types/reenter_question_mark.html diff --git a/src/flow_control/match/destructuring/destructure_enum.md b/src/flow_control/match/destructuring/destructure_enum.md index 1046e527ca..a5022330ba 100644 --- a/src/flow_control/match/destructuring/destructure_enum.md +++ b/src/flow_control/match/destructuring/destructure_enum.md @@ -49,6 +49,6 @@ fn main() { [`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] -[allow]: /attribute/unused.html +[allow]: attribute/unused.html [color_models]: https://en.wikipedia.org/wiki/Color_model -[enum]: /custom_types/enum.html +[enum]: custom_types/enum.html diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index a4a23c90cc..d641c669b6 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -29,4 +29,4 @@ fn main() { ### See also: -[Structs](/custom_types/structs.html), [The ref pattern](/scope/borrow/ref.html) +[Structs](custom_types/structs.html), [The ref pattern](scope/borrow/ref.html) diff --git a/src/flow_control/match/destructuring/destructure_tuple.md b/src/flow_control/match/destructuring/destructure_tuple.md index a29b1a802d..c7e1024aca 100644 --- a/src/flow_control/match/destructuring/destructure_tuple.md +++ b/src/flow_control/match/destructuring/destructure_tuple.md @@ -21,4 +21,4 @@ fn main() { ### See also: -[Tuples](/primitives/tuples.html) +[Tuples](primitives/tuples.html) diff --git a/src/macros/syntax.md b/src/macros/syntax.md index 435d64e21d..16082586f0 100644 --- a/src/macros/syntax.md +++ b/src/macros/syntax.md @@ -3,6 +3,10 @@ In following subsections, we will show how to define macros in Rust. There are three basic ideas: -- [Patterns and Designators](macros/designators.md) -- [Overloading](macros/overload.md) -- [Repetition](macros/repeat.md) +- [Patterns and Designators][designators] +- [Overloading][overloading] +- [Repetition][repetition] + +[designators]: macros/designators.html +[overloading]: macros/overload.html +[repetition]: macros/repeat.html diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 97aa37a989..61fc258c00 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -140,13 +140,13 @@ defined by a static constant at the beginning of the program. * [unwrap vs. expect][unwrap] * [enumerate][enumerate] -[thread]: /std_misc/threads.html -[vectors]: /std/vec.html -[iterators]: /trait/iter.html +[thread]: std_misc/threads.html +[vectors]: std/vec.html +[iterators]: trait/iter.html [destructuring]: https://doc.rust-lang.org/book/second-edition/ch18-03-pattern-syntax.html#destructuring-to-break-apart-values -[closures]: /fn/closures.html -[move]: /scope/move.html +[closures]: fn/closures.html +[move]: scope/move.html [move_closure]: https://doc.rust-lang.org/book/second-edition/ch13-01-closures.html#closures-can-capture-their-environment [turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect -[unwrap]: /error/option_unwrap.html +[unwrap]: error/option_unwrap.html [enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate diff --git a/src/unsafe.md b/src/unsafe.md index f0e5d6c278..b0d2023fc6 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -8,7 +8,7 @@ unsafe blocks are used for: * dereferencing raw pointers * calling a function over FFI (but this is covered in [a previous - chapter](/std_misc/ffi.html) of the book) + chapter](std_misc/ffi.html) of the book) * changing types through `std::mem::transmute` * inline assembly From 7394d1407a5e63e5b23cd05cc3593aa2ab21dfaa Mon Sep 17 00:00:00 2001 From: Michael Bryan Date: Fri, 29 Dec 2017 16:06:25 +0800 Subject: [PATCH 0755/1122] Talk about `unsafe` functions in general instead of just `transmute` --- src/unsafe.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/unsafe.md b/src/unsafe.md index b0d2023fc6..c5143d496f 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -9,7 +9,7 @@ unsafe blocks are used for: * dereferencing raw pointers * calling a function over FFI (but this is covered in [a previous chapter](std_misc/ffi.html) of the book) -* changing types through `std::mem::transmute` +* calling functions which are `unsafe` * inline assembly ### Raw Pointers @@ -28,18 +28,34 @@ fn main() { } ``` -### Transmute -Allows simple conversion from one type to another, however both types must have -the same size and alignment: +### Calling Unsafe Functions +Some functions can be declared as `unsafe`, meaning it is the programmer's +responsibility to ensure correctness instead of the compiler's. One example +of this is [`std::slice::from_raw_parts`] which will create a slice given a +pointer to the first element and a length. ```rust,editable +use std::slice; + fn main() { - let u: &[u8] = &[49, 50, 51]; + let some_vector = vec![1, 2, 3, 4]; + + let pointer = some_vector.as_ptr(); + let length = some_vector.len(); unsafe { - assert!(u == std::mem::transmute::<&str, &[u8]>("123")); + let my_slice: &[u32] = slice::from_raw_parts(pointer, length); + + assert_eq!(some_vector.as_slice(), my_slice); } } ``` +For `slice::from_raw_parts`, one of the assumptions which *must* be upheld is +that the pointer passed in points to valid memory and that the memory pointed to +is of the correct type. If these invariants aren't upheld then the program's +behaviour is undefined and there is no knowing what will happen. + + [unsafe]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html +[`std::slice::from_raw_parts`]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html From 873ef312320d1ade699821225ff276549abd73f3 Mon Sep 17 00:00:00 2001 From: Damian Carrillo Date: Sat, 13 Jan 2018 21:57:54 -0600 Subject: [PATCH 0756/1122] Fixing a misspelled word "Capabilities" was misspelled in chapter 12.3. This revision fixes it. --- src/cargo/conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index ae7cab0d83..3969af0cb3 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -30,7 +30,7 @@ binaries, we just pass cargo the `--bin my_other_bin` flag, where `my_other_bin` is the name of the binary we want to work with. In addition to extra binaries, there is support for benchmarks, tests, and -examples. The full capaibilities are documented +examples. The full capabilities are documented [here](http://doc.crates.io/book/guide/project-layout.html). In the next chapter, we will look more closely at tests. From d218b4e59e2abaa19c0a142af47937fb9d2e0b9e Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 07:30:54 +0300 Subject: [PATCH 0757/1122] fix typo --- src/conversion/from_into.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conversion/from_into.md b/src/conversion/from_into.md index c27645a1c8..9be8bc24ad 100644 --- a/src/conversion/from_into.md +++ b/src/conversion/from_into.md @@ -48,7 +48,7 @@ implementation for free. Using the `Into` trait will typically require specification of the type to convert into as the compiler is unable to determine this most of the time. -However this is a small trade off considering we get the functionality for free. +However this is a small trade-off considering we get the functionality for free. ```rust,editable use std::convert::From; From a48d5fd74e5163146ff07e032de45a28c94e5c38 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 09:45:27 +0300 Subject: [PATCH 0758/1122] reword definition to be more precise I used this comment // This declaration will look for a file named `my.rs` or `my/mod.rs` and will // insert its contents inside a module named `my` under this scope from [book's previous page](https://rustbyexample.com/mod/split.html]) --- src/crates.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/crates.md b/src/crates.md index 44f714bee3..4c46e553cd 100644 --- a/src/crates.md +++ b/src/crates.md @@ -2,10 +2,11 @@ A crate is a compilation unit in Rust. Whenever `rustc some_file.rs` is called, `some_file.rs` is treated as the *crate file*. If `some_file.rs` has `mod` -declarations in it, then the contents of the module files will get merged with -the crate file *before* running the compiler over it. In other words, modules -do *not* get compiled individually, only crates get compiled. +declarations in it, then the contents of the module files would be inserted in +places where `mod` declarations in the crate file are found, *before* running +the compiler over it. In other words, modules do *not* get compiled +individually, only crates get compiled. A crate can be compiled into a binary or into a library. By default, `rustc` will produce a binary from a crate. This behavior can be overridden by passing -the `--crate-type` flag to `rustc`. \ No newline at end of file +the `--crate-type` flag to `rustc`. From 9bce6306c219bb6e7527d4c4f320e17e33185a9c Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 09:59:36 +0300 Subject: [PATCH 0759/1122] fix typo --- src/cargo/deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 6115e771e9..495405d09e 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -85,4 +85,4 @@ run. Notice that these commands will resolve all dependencies, download crates if needed, and build everything, including your crate. (Note that it only rebuilds what it has not already built, similar to `make`). -Voila! That's all there is too it! +Voila! That's all there is to it! From 0a4dfdab39b548e0db798864199dfcca9584cb08 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 20:04:22 +0300 Subject: [PATCH 0760/1122] fix typo --- src/cargo/conventions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index ae7cab0d83..b0d62a85e5 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -12,7 +12,7 @@ foo Suppose that we wanted to have two binaries in the same project, though. What then? -It turns out that cargo supports this. The default binary name is `main.rs`, as +It turns out that `cargo` supports this. The default binary name is `main.rs`, as we saw before, but you can add additional binaries by placing them in a `bin/` directory: @@ -25,8 +25,8 @@ foo └── my_other_bin.rs ``` -To tell cargo to compile or run this binary as opposed to the default or other -binaries, we just pass cargo the `--bin my_other_bin` flag, where `my_other_bin` +To tell `cargo` to compile or run this binary as opposed to the default or other +binaries, we just pass `cargo` the `--bin my_other_bin` flag, where `my_other_bin` is the name of the binary we want to work with. In addition to extra binaries, there is support for benchmarks, tests, and From 4fa4820cdd38161ffb1586b6a5d3d6b837ff3a1b Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 20:07:19 +0300 Subject: [PATCH 0761/1122] fix typo --- src/scope/borrow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/borrow.md b/src/scope/borrow.md index c3e65e251b..e38b717b89 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -2,7 +2,7 @@ Most of the time, we'd like to access data without taking ownership over it. To accomplish this, Rust uses a *borrowing* mechanism. Instead of -passing objects by-value (`T`), objects can be passed by reference (`&T`). +passing objects by value (`T`), objects can be passed by reference (`&T`). The compiler statically guarantees (via its borrow checker) that references *always* point to valid objects. That is, while references to an object From 5cac496ff4d118da3021937fc6c1c4b3daa12683 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 20:27:40 +0300 Subject: [PATCH 0762/1122] fix typo --- src/scope/lifetime/struct.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/lifetime/struct.md b/src/scope/lifetime/struct.md index 2951bcc539..3b33da3ee6 100644 --- a/src/scope/lifetime/struct.md +++ b/src/scope/lifetime/struct.md @@ -40,7 +40,7 @@ fn main() { ### See also: -[`structs`][structs] +[`struct`s][structs] [structs]: custom_types/structs.html From 0abe2035018b1afed120e071388ad356eb73aff2 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Mon, 15 Jan 2018 23:46:34 +0300 Subject: [PATCH 0763/1122] fix typo --- src/error/multiple_error_types/wrap_error.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index 5dd8083aa2..bdd1dbe220 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -83,8 +83,8 @@ fn main() { ``` This adds a bit more boilerplate for handling errors and might not be needed in -all applications. There are some libraries that can take care of the boiler -plate for you. +all applications. There are some libraries that can take care of the boilerplate +for you. ### See also: From c4c8b2076692270e30aa01b73e73199781757312 Mon Sep 17 00:00:00 2001 From: Bulat Musin Date: Tue, 16 Jan 2018 08:51:33 +0300 Subject: [PATCH 0764/1122] move change into capture.md --- src/fn/closures/capture.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index df2ce02cba..03cdcf67ca 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -69,6 +69,30 @@ fn main() { } ``` +Using `move` before vertical pipes forces closure +to take ownership of captured variables: + +```rust,editable +fn main() { + // `Vec` has non-copy semantics. + let haystack = vec![1, 2, 3]; + + let contains = move |needle| haystack.contains(needle); + + println!("{}", contains(&1)); + println!("{}", contains(&4)); + + // `println!("There're {} elements in vec", haystack.len());` + // ^ Uncommenting above line will result in compile-time error + // because borrow checker doesn't allow re-using variable after it + // has been moved. + + // Removing `move` from closure's signature will cause closure + // to borrow _haystack_ variable immutably, hence _haystack_ is still + // available and uncommenting above line will not cause an error. +} +``` + ### See also: [`Box`][box] and [`std::mem::drop`][drop] From 37e3f5f933312cd3f8b011b68669ed1d914c9c64 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 11:14:48 +0300 Subject: [PATCH 0765/1122] fix incorrect note --- src/std/result/question_mark.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std/result/question_mark.md b/src/std/result/question_mark.md index 5415191865..c51cc638f6 100644 --- a/src/std/result/question_mark.md +++ b/src/std/result/question_mark.md @@ -3,8 +3,8 @@ Chaining results using match can get pretty untidy; luckily, the `?` operator can be used to make things pretty again. `?` is used at the end of an expression returning a `Result`, and is equivalent to a match expression, where the -`Err(err)` branch expands to an early `return Err(err)`, and the `Ok(ok)` branch -expands to an `ok` expression. +`Err(err)` branch expands to an early `Err(From::from(err))`, and the `Ok(ok)` +branch expands to an `ok` expression. ```rust,editable,ignore,mdbook-runnable mod checked { From f81977adb5b377bacdfdbaee7750ea48a9b008bb Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 11:21:27 +0300 Subject: [PATCH 0766/1122] remove redundant parentheses --- src/std/hash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/hash.md b/src/std/hash.md index 7b736815c2..94faacbf25 100644 --- a/src/std/hash.md +++ b/src/std/hash.md @@ -47,7 +47,7 @@ fn main() { _ => println!("Don't have Ashley's number."), } - contacts.remove(&("Ashley")); + contacts.remove(&"Ashley"); // `HashMap::iter()` returns an iterator that yields // (&'a key, &'a value) pairs in arbitrary order. From ee3969caee725eda2d4177f8c050bd742974f833 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 11:25:11 +0300 Subject: [PATCH 0767/1122] replace . with : for consistency In other places : is used instead of dot. --- src/std/hash/hashset.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/hash/hashset.md b/src/std/hash/hashset.md index 3d83717501..760ec19969 100644 --- a/src/std/hash/hashset.md +++ b/src/std/hash/hashset.md @@ -30,7 +30,7 @@ Sets have 4 primary operations (all of the following calls return an iterator): * `symmetric_difference`: get all the elements that are in one set or the other, but *not* both. -Try all of these in the following example. +Try all of these in the following example: ```rust,editable,ignore,mdbook-runnable use std::collections::HashSet; From 74e55c66edf52728fbfa4ce15fd2200bb94b653c Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 11:26:59 +0300 Subject: [PATCH 0768/1122] fix grammar error --- src/std/hash/hashset.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/hash/hashset.md b/src/std/hash/hashset.md index 3d83717501..48211b821e 100644 --- a/src/std/hash/hashset.md +++ b/src/std/hash/hashset.md @@ -70,7 +70,7 @@ fn main() { } ``` -(Examples adapted from the [documentation.][hash-set]) +(Examples are adapted from the [documentation.][hash-set]) [treeset]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html [hash-set]: https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.difference From 7b2cd378b1a705c9b75c338c7ea8f2aff82e1024 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 13:14:54 +0300 Subject: [PATCH 0769/1122] fix typo --- src/std_misc/arg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md index 4d5ba95241..f547abfb40 100644 --- a/src/std_misc/arg.md +++ b/src/std_misc/arg.md @@ -30,7 +30,7 @@ I got 3 arguments: ["1", "2", "3"]. ## Crates Alternatively, there are numerous crates that can provide extra functionality -when creating command line applications. The [Rust Cookbook] exhibits best +when creating command-line applications. The [Rust Cookbook] exhibits best practices on how to use one of the more popular command line argument crates, `clap`. From a27eff58eaa85ab22326dff3ba556435240f234a Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 13:41:39 +0300 Subject: [PATCH 0770/1122] collapse two examples into one to simplify reading --- src/std_misc/ffi.md | 53 +++++++++------------------------------------ 1 file changed, 10 insertions(+), 43 deletions(-) diff --git a/src/std_misc/ffi.md b/src/std_misc/ffi.md index 84b1742cb5..71977e66fa 100644 --- a/src/std_misc/ffi.md +++ b/src/std_misc/ffi.md @@ -13,59 +13,26 @@ extern { // this is a foreign function // that computes the square root of a single precision complex number fn csqrtf(z: Complex) -> Complex; -} - -fn main() { - // z = -1 + 0i - let z = Complex { re: -1., im: 0. }; - // calling a foreign function is an unsafe operation - let z_sqrt = unsafe { - csqrtf(z) - }; - - println!("the square root of {:?} is {:?}", z, z_sqrt); -} - -// Minimal implementation of single precision complex numbers -#[repr(C)] -#[derive(Clone, Copy)] -struct Complex { - re: f32, - im: f32, -} - -impl fmt::Debug for Complex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.im < 0. { - write!(f, "{}-{}i", self.re, -self.im) - } else { - write!(f, "{}+{}i", self.re, self.im) - } - } -} -``` - -Since calling foreign functions is considered unsafe, it's common to write safe -wrappers around them. - -```rust,ignore -use std::fmt; - -#[link(name = "m")] -extern { fn ccosf(z: Complex) -> Complex; } -// safe wrapper +// Since calling foreign functions is considered unsafe, +// it's common to write safe wrappers around them. fn cos(z: Complex) -> Complex { unsafe { ccosf(z) } } fn main() { - // z = 0 + 1i - let z = Complex { re: 0., im: 1. }; + // z = -1 + 0i + let z = Complex { re: -1., im: 0. }; + + // calling a foreign function is an unsafe operation + let z_sqrt = unsafe { csqrtf(z) }; + + println!("the square root of {:?} is {:?}", z, z_sqrt); + // calling safe API wrapped around unsafe operation println!("cos({:?}) = {:?}", z, cos(z)); } From 755897cc07ff21e3a3e31ca4e1cd536130220b34 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 13:24:35 +0300 Subject: [PATCH 0771/1122] change println -> eprintln where appropriate --- src/std_misc/arg/matching.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/std_misc/arg/matching.md b/src/std_misc/arg/matching.md index 03942683f3..984b05d92f 100644 --- a/src/std_misc/arg/matching.md +++ b/src/std_misc/arg/matching.md @@ -46,7 +46,7 @@ fn main() { n }, Err(_) => { - println!("error: second argument not an integer"); + eprintln!("error: second argument not an integer"); help(); return; }, @@ -56,7 +56,7 @@ fn main() { "increase" => increase(number), "decrease" => decrease(number), _ => { - println!("error: invalid command"); + eprintln!("error: invalid command"); help(); }, } @@ -91,4 +91,4 @@ match_args {increase|decrease} Increase or decrease given integer by one. $ ./match_args increase 42 43 -``` \ No newline at end of file +``` From e71ee290fe3931ca9f8d6f53d508ba115e2278c0 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Tue, 16 Jan 2018 15:31:04 +0300 Subject: [PATCH 0772/1122] change case rust -> Rust --- src/testing/integration_testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index 1906b2b131..ba66ff0242 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -50,7 +50,7 @@ running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` -Each rust source file in `tests` directory is compiled as a separate crate. One +Each Rust source file in `tests` directory is compiled as a separate crate. One way of sharing some code between integration tests is making module with public functions, importing and using it within tests. From 6f46abc8867435eb45dd50b068c8decab3cc7f04 Mon Sep 17 00:00:00 2001 From: Mario Idival Date: Tue, 16 Jan 2018 20:47:01 -0300 Subject: [PATCH 0773/1122] Add example to partial struct's copies --- src/custom_types/structs.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 1b201b2921..f8c766ac41 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -74,6 +74,26 @@ fn main() { } ``` +A `struct` can include `..` to indicate that you want to use a copy of some other struct for some of the values. +This gives `Triplet` a new `third`, but keeps the old `first` and `second` values. It doesn’t have to be the same struct either, you can use this syntax when making new ones, and it will copy the values you don’t specify, For example: + +```rust,editable +#[derive(Debug)] +struct Triplet { + first: i32, + second: i32, + third: i32, +} + +fn main() { + let t = Triplet { first: 0, second: 1, third: 2 }; + let u = Triplet { first: 3, .. t }; + + println!("{:?}", t); + println!("{:?}", u); +} +``` + ### Activity 1. Add a function `rect_area` which calculates the area of a rectangle (try From a18f1eb54b8b19cc1184897a224074bd3c6210d9 Mon Sep 17 00:00:00 2001 From: Mario Idival Date: Tue, 16 Jan 2018 21:18:22 -0300 Subject: [PATCH 0774/1122] Update example te be equal the explanation --- src/custom_types/structs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index f8c766ac41..418201379f 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -86,8 +86,8 @@ struct Triplet { } fn main() { - let t = Triplet { first: 0, second: 1, third: 2 }; - let u = Triplet { first: 3, .. t }; + let t = Triplet { first: 1, second: 2, third: 2 }; + let u = Triplet { third: 3, .. t }; println!("{:?}", t); println!("{:?}", u); From ec98f5a21f6caf34b30cdd3766b54d51866e8a15 Mon Sep 17 00:00:00 2001 From: Kirill Danshin Date: Wed, 17 Jan 2018 04:07:33 +0300 Subject: [PATCH 0775/1122] hello/comment.md: Fix indentation --- src/hello/comment.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hello/comment.md b/src/hello/comment.md index fc116c1650..951b7df858 100644 --- a/src/hello/comment.md +++ b/src/hello/comment.md @@ -30,16 +30,16 @@ fn main() { * in this main() function. /*/*/* Try it yourself! */*/*/ */ - /* - Note, the previous column of `*` was entirely for style. There's - no actual need for it. - */ - - // Observe how block comments allow easy expression manipulation - // which line comments do not. Deleting the comment delimiters - // will change the result: - let x = 5 + /* 90 + */ 5; - println!("Is `x` 10 or 100? x = {}", x); + /* + Note, the previous column of `*` was entirely for style. There's + no actual need for it. + */ + + // Observe how block comments allow easy expression manipulation + // which line comments do not. Deleting the comment delimiters + // will change the result: + let x = 5 + /* 90 + */ 5; + println!("Is `x` 10 or 100? x = {}", x); } ``` From 60aa5f98d1b20646e54ed17a2c75a7683a2e45a9 Mon Sep 17 00:00:00 2001 From: brieucdesoutter <30637345+brieucdesoutter@users.noreply.github.com> Date: Wed, 17 Jan 2018 16:43:42 +0100 Subject: [PATCH 0776/1122] fixed small typos --- src/cargo/deps.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 495405d09e..c7cc871e39 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -1,8 +1,8 @@ # Dependencies Most programs have dependencies on some libraries. If you have ever managed -dependencies by hand, you know how much of a pain this. Luckily, the Rust -ecosystem comes standard with `cargo`! `cargo` can manage dependcies for a +dependencies by hand, you know how much of a pain this can be. Luckily, the Rust +ecosystem comes standard with `cargo`! `cargo` can manage dependencies for a project. To create a new Rust project, From 110b15c2c0a99dde67f842a606c73805dff21696 Mon Sep 17 00:00:00 2001 From: Bulat Musin <9249387+bmusin@users.noreply.github.com> Date: Sun, 14 Jan 2018 08:06:14 +0300 Subject: [PATCH 0777/1122] refine wording --- src/fn/closures.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fn/closures.md b/src/fn/closures.md index 1c3c17b9db..a26cb2089c 100644 --- a/src/fn/closures.md +++ b/src/fn/closures.md @@ -1,6 +1,6 @@ # Closures -Closures in Rust, also called lambdas, are functions that can capture +Closures in Rust, also called lambda expressions or lambdas, are functions that can capture the enclosing environment. For example, a closure that captures the x variable: ```Rust @@ -41,4 +41,4 @@ fn main() { println!("closure returning one: {}", one()); } -``` \ No newline at end of file +``` From 3b4a0dc73f437f63d2666baaab971fcef6455634 Mon Sep 17 00:00:00 2001 From: Mario Idival Date: Wed, 17 Jan 2018 23:47:11 -0300 Subject: [PATCH 0778/1122] Update example to struct update syntax --- src/custom_types/structs.md | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 418201379f..f51d67a74d 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -38,17 +38,22 @@ fn main() { let name = "Peter"; let age = 27; let peter = Person { name, age }; - + // Print debug struct println!("{:?}", peter); - - + + // Instantiate a `Point` let point: Point = Point { x: 0.3, y: 0.4 }; // Access the fields of the point println!("point coordinates: ({}, {})", point.x, point.y); + // Make a new point by using struct update syntax to use the fields of our other one + let new_point = Point { x: 0.1, ..point }; + // `new_point.y` will be the same as `point.y` because we used that field from `point` + println!("second point: ({}, {})", new_point.x, new_point.y); + // Destructure the point using a `let` binding let Point { x: my_x, y: my_y } = point; @@ -74,26 +79,6 @@ fn main() { } ``` -A `struct` can include `..` to indicate that you want to use a copy of some other struct for some of the values. -This gives `Triplet` a new `third`, but keeps the old `first` and `second` values. It doesn’t have to be the same struct either, you can use this syntax when making new ones, and it will copy the values you don’t specify, For example: - -```rust,editable -#[derive(Debug)] -struct Triplet { - first: i32, - second: i32, - third: i32, -} - -fn main() { - let t = Triplet { first: 1, second: 2, third: 2 }; - let u = Triplet { third: 3, .. t }; - - println!("{:?}", t); - println!("{:?}", u); -} -``` - ### Activity 1. Add a function `rect_area` which calculates the area of a rectangle (try From 7b67f435687a77e14f20b471dca7df21f0f9644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20G=C3=A4rtner?= Date: Sun, 21 Jan 2018 12:39:27 +0100 Subject: [PATCH 0779/1122] add wrapping main function for examples execution --- src/flow_control/for.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index e6f219d7fc..1c91965996 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -42,12 +42,14 @@ collection. Thus leaving the collection untouched and available for reuse after the loop. ```rust, editable -let names = vec!["Bob", "Frank", "Ferris"]; +fn main() { + let names = vec!["Bob", "Frank", "Ferris"]; -for name in names.iter() { - match name { - &"Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), + for name in names.iter() { + match name { + &"Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } } } ``` @@ -57,12 +59,14 @@ for name in names.iter() { available for reuse as it has been 'moved' within the loop. ```rust, editable -let names = vec!["Bob", "Frank", "Ferris"]; +fn main() { + let names = vec!["Bob", "Frank", "Ferris"]; -for name in names.into_iter() { - match name { - "Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), + for name in names.into_iter() { + match name { + "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } } } ``` @@ -71,12 +75,14 @@ for name in names.into_iter() { the collection to be modified in place. ```rust, editable -let mut names = vec!["Bob", "Frank", "Ferris"]; +fn main() { + let mut names = vec!["Bob", "Frank", "Ferris"]; -for name in names.iter_mut() { - match name { - &mut "Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), + for name in names.iter_mut() { + match name { + &mut "Ferris" => println!("There is a rustacean among us!"), + _ => println!("Hello {}", name), + } } } ``` From ea3385c40c0773cf458d1bae6ed3a6e0503e3d1d Mon Sep 17 00:00:00 2001 From: Alexis Hunt Date: Wed, 24 Jan 2018 20:11:04 -0500 Subject: [PATCH 0780/1122] Document inclusive ranges. This provides documentation for rust-lang/rust#28237. --- src/flow_control/for.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 1c91965996..f4d5672ab6 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -26,6 +26,26 @@ fn main() { } ``` +Alternatively, `a..=b` can be used for a range that is inclusive on both ends. +The above can be written as: + +```rust,editable +fn main() { + // `n` will take the values: 1, 2, ..., 100 in each iteration + for n in 1..=100 { + if n % 15 == 0 { + println!("fizzbuzz"); + } else if n % 3 == 0 { + println!("fizz"); + } else if n % 5 == 0 { + println!("buzz"); + } else { + println!("{}", n); + } + } +} +``` + ## for and iterators The `for in` construct is able to interact with an `Iterator` in several ways. From d10ca39fe9e0057260a45b48df07e0a7a31259c1 Mon Sep 17 00:00:00 2001 From: Michel Zimmer Date: Thu, 25 Jan 2018 14:29:02 +0100 Subject: [PATCH 0781/1122] Simplify new type idiom example Signed-off-by: Michel Zimmer --- src/generics/new_types.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index 2ac7dc7f63..47d530135d 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -26,10 +26,7 @@ impl Days { } fn old_enough(age: &Years) -> bool { - if age.0 >= 18 { - return true - } - false + age.0 >= 18 } fn main() { From 06f15b272f9a60ccb6e1819cff358da106877a35 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 Jan 2018 02:56:16 +0300 Subject: [PATCH 0782/1122] Fix failing tidy on Windows --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d56abbf304 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto eol=lf From 51e90f6d4ea513177f71a7257660430d83593f05 Mon Sep 17 00:00:00 2001 From: Tal Nordan Date: Sat, 27 Jan 2018 21:58:20 -0800 Subject: [PATCH 0783/1122] testcase_linked_list.md: Fix comment --- src/custom_types/enum/testcase_linked_list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index c678d62c97..3c10ed61c2 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -60,7 +60,7 @@ fn main() { // Create an empty linked list let mut list = List::new(); - // Append some elements + // Prepend some elements list = list.prepend(1); list = list.prepend(2); list = list.prepend(3); From 24933949cb5d286112da86e8cd25ee0296aa94c8 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Tue, 30 Jan 2018 09:22:08 +0100 Subject: [PATCH 0784/1122] Add more attribute examples --- src/attribute.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/attribute.md b/src/attribute.md index d945dd9123..1b81c09976 100644 --- a/src/attribute.md +++ b/src/attribute.md @@ -23,6 +23,16 @@ Attributes can take arguments with different syntaxes: * `#[attribute(key = "value")]` * `#[attribute(value)]` +Attributes can have multiple values and can be separated over multiple lines, too: + +```rust,ignore +#[attribute(value, value2)] + + +#[attribute(value, value2, value3, + value4, value5)] +``` + [cfg]: attribute/cfg.html [crate]: attribute/crate.html [lint]: https://en.wikipedia.org/wiki/Lint_%28software%29 From c9e7220694115d537e937c72919894b703e4f6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Podg=C3=B3rski?= Date: Tue, 6 Feb 2018 22:28:28 +0100 Subject: [PATCH 0785/1122] Update conventions.md --- src/cargo/conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index ff40ec7da8..8b613925d2 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -1,6 +1,6 @@ # Conventions -In the previous chapter, we saw the following directory heirarcy: +In the previous chapter, we saw the following directory hierarchy: ```txt foo From 6eb016d1df7ba938498be42bb70346bf97021321 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Feb 2018 11:04:22 +0100 Subject: [PATCH 0786/1122] Fix rustdoc errors --- src/hello/print/print_display.md | 3 ++- src/macros/variadics.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 90385aac66..5bf4460514 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -110,7 +110,8 @@ each requires its own implementation. This is detailed further in After checking the output of the above example, use the `Point2D` struct as guide to add a Complex struct to the example. When printed in the same way, the output should be: -``` + +```txt Display: 3.3 +7.2i Debug: Complex { real: 3.3, imag: 7.2 } ``` diff --git a/src/macros/variadics.md b/src/macros/variadics.md index 5de3a52d34..e0cb1c1239 100644 --- a/src/macros/variadics.md +++ b/src/macros/variadics.md @@ -33,7 +33,8 @@ fn main() { ``` Output: -``` + +```txt 1 + 2 = 3 3 + 4 = 7 (2 * 3) + 1 = 7 From a5ff18ec640d7745c361fd7140fedf4be0130263 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Feb 2018 15:50:51 +0100 Subject: [PATCH 0787/1122] Fix another rustdoc test error --- src/macros/dsl.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/macros/dsl.md b/src/macros/dsl.md index cdb08d0162..1182b97cc7 100644 --- a/src/macros/dsl.md +++ b/src/macros/dsl.md @@ -30,7 +30,8 @@ fn main() { ``` Output: -``` + +```txt 1 + 2 = 3 (1 + 2) * (3 / 4) = 0 ``` From effdf1db39f9ddd214c8a76e7df7ac35f830e172 Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 28 Feb 2018 21:09:35 +0000 Subject: [PATCH 0788/1122] Minor change. Replaced wrong 'reduce by two' with 'half the number' --- src/flow_control/if_else.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/if_else.md b/src/flow_control/if_else.md index a8d53ee408..01c5d1a4b7 100644 --- a/src/flow_control/if_else.md +++ b/src/flow_control/if_else.md @@ -24,7 +24,7 @@ fn main() { // This expression returns an `i32`. 10 * n } else { - println!(", and is a big number, reduce by two"); + println!(", and is a big number, half the number"); // This expression must return an `i32` as well. n / 2 @@ -34,4 +34,4 @@ fn main() { println!("{} -> {}", n, big_n); } -``` \ No newline at end of file +``` From 7fe4b01dc7942fa751008d744b504801fb1b2a30 Mon Sep 17 00:00:00 2001 From: Songbird0 Date: Sun, 11 Mar 2018 23:54:38 +0100 Subject: [PATCH 0789/1122] Add link to french RBE translation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 632c1f0cc3..e2403d504c 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Please see the [CONTRIBUTING.md] file for more details. * [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) * [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) +* [French](https://github.com/Songbird0/FR_RBE) ## License From b421d2ef6d33baa9890edfbfe70a3a37ac3359d2 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 14 Mar 2018 20:39:05 -0400 Subject: [PATCH 0790/1122] =?UTF-8?q?Don=E2=80=99t=20install=20mdbook=20if?= =?UTF-8?q?=20latest=20version=20is=20already=20installed.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/rust-lang/rust-by-example/issues/1025. --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9b2b10319a..952d86c87d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,12 @@ branches: only: - master before_script: - - (cargo install mdbook --git https://github.com/azerupi/mdBook.git --force || true) + - | + LATEST=$(cargo search mdbook | grep "^mdbook =" | cut -d '"' -f 2) + INSTALLED=$(cargo install --list | grep "^mdbook " | cut -d v -f 2 | tr -d :) + if [ "$INSTALLED" != "$LATEST" ]; then + cargo install mdbook --force + fi script: - mdbook build - mdbook test From 6064cb36b809088237d56a5c74de55583a2ef9b0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 14 Mar 2018 21:54:59 -0400 Subject: [PATCH 0791/1122] empty commit. From 01474f6c066e825d4d8e25ac8c97450ea72f042a Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 14 Mar 2018 21:59:50 -0400 Subject: [PATCH 0792/1122] add some logging --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 952d86c87d..143b0779d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ before_script: LATEST=$(cargo search mdbook | grep "^mdbook =" | cut -d '"' -f 2) INSTALLED=$(cargo install --list | grep "^mdbook " | cut -d v -f 2 | tr -d :) if [ "$INSTALLED" != "$LATEST" ]; then + echo "mdbook $INSTALLED is already installed. Updating to mdbook $LATEST." cargo install mdbook --force fi script: From b07a4ef9b5bc2f2baaafeca35eca7183d9ccb407 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 14 Mar 2018 22:12:44 -0400 Subject: [PATCH 0793/1122] even better logging --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 143b0779d2..75ec7d88eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,11 @@ before_script: LATEST=$(cargo search mdbook | grep "^mdbook =" | cut -d '"' -f 2) INSTALLED=$(cargo install --list | grep "^mdbook " | cut -d v -f 2 | tr -d :) if [ "$INSTALLED" != "$LATEST" ]; then - echo "mdbook $INSTALLED is already installed. Updating to mdbook $LATEST." - cargo install mdbook --force + if [ "INSTALLED" != "" ]; then + echo "mdbook '$INSTALLED' is already installed" + fi + echo "Installing mdbook '$LATEST'" + cargo install mdbook --force --vers "$LATEST" fi script: - mdbook build From 14e2fc848486aff99957760cfced174c1bce028c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 14 Mar 2018 22:42:45 -0400 Subject: [PATCH 0794/1122] typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 75ec7d88eb..94564dc5c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_script: LATEST=$(cargo search mdbook | grep "^mdbook =" | cut -d '"' -f 2) INSTALLED=$(cargo install --list | grep "^mdbook " | cut -d v -f 2 | tr -d :) if [ "$INSTALLED" != "$LATEST" ]; then - if [ "INSTALLED" != "" ]; then + if [ "$INSTALLED" != "" ]; then echo "mdbook '$INSTALLED' is already installed" fi echo "Installing mdbook '$LATEST'" From a1737ffd6a24f007db7bf9a1ad97b64e7d324825 Mon Sep 17 00:00:00 2001 From: Martin Sehnoutka Date: Fri, 16 Mar 2018 14:50:13 +0100 Subject: [PATCH 0795/1122] Add section about diverging functions --- src/SUMMARY.md | 1 + src/fn/diverging.md | 69 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/fn/diverging.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index de7e6f6ee7..2a735e4057 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -70,6 +70,7 @@ - [Iterator::any](fn/closures/closure_examples/iter_any.md) - [Iterator::find](fn/closures/closure_examples/iter_find.md) - [Higher Order Functions](fn/hof.md) + - [Diverging functions](fn/diverging.md) - [Modules](mod.md) - [Visibility](mod/visibility.md) diff --git a/src/fn/diverging.md b/src/fn/diverging.md new file mode 100644 index 0000000000..d1f3e7bf42 --- /dev/null +++ b/src/fn/diverging.md @@ -0,0 +1,69 @@ +# Diverging functions + +Diverging functions never return. They are marked using `!`, which is an empty type. + +```rust +fn foo() -> ! { + panic!("This call never returns."); +} +``` + +As opposed to all the other types, this one cannot be instantiated, because the +set of all possible values this type can have is empty. Note, that it is +different from the `()` type, which has exactly one possible value. + +For example, this functions returns as usual, although there is no information +in the return value. + +```rust +fn some_fn() { + () +} + +fn main() { + let a: () = some_fn(); + println!("This functions returns and you can see this line.") +} +``` + +As opposed to this function, which will never return the control back to the caller. + +```rust,ignore +#![feature(never_type)] + +fn main() { + let x: ! = panic!("This call never returns."); + println!("You will never see this line!"); +} +``` + +Although this might seem like an abstract concept, it is in fact very useful and +often handy. The main advantage of this type is that it can be cast to any other +one and therefore used at places where an exact type is required, for instance +in `match` branches. This allows us to write code like this: + +```rust +fn main() { + fn sum_odd_numbers(up_to: u32) -> u32 { + let mut acc = 0; + for i in 0..up_to { + // Notice that the return type of this match expression must be u32 + // because of the type of the "addition" variable. + let addition: u32 = match i%2 == 1 { + // The "i" variable is of type u32, which is perfectly fine. + true => i, + // On the other hand, the "continue" expression does not return + // u32, but it is still fine, because it never returns and therefore + // does not violate the type requirements of the match expression. + false => continue, + }; + acc += addition; + } + acc + } + println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9)); +} +``` + +It is also the return type of functions that loop forever (e.g. `loop {}`) like +network servers or functions that terminates the process (e.g. `exit()`). From c541183a0dd9d3739ee0c6d97001ad7d90385c6e Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 27 Mar 2018 16:31:27 +0200 Subject: [PATCH 0796/1122] Run Rust nightly on Travis for CI. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 94564dc5c6..78e93d6d3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: false language: rust cache: cargo rust: - - stable + - nightly branches: only: - master From b07f5b493f841c43db02762113518ea162535e39 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 27 Mar 2018 17:36:25 +0200 Subject: [PATCH 0797/1122] Capitalize page names. --- src/SUMMARY.md | 4 ++-- src/scope/lifetime/elision.md | 2 +- src/scope/lifetime/static_lifetime.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 09d9e39f81..d67ad3e49b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -125,8 +125,8 @@ - [Structs](scope/lifetime/struct.md) - [Bounds](scope/lifetime/lifetime_bounds.md) - [Coercion](scope/lifetime/lifetime_coercion.md) - - [static](scope/lifetime/static_lifetime.md) - - [elision](scope/lifetime/elision.md) + - [Static](scope/lifetime/static_lifetime.md) + - [Elision](scope/lifetime/elision.md) - [Traits](trait.md) - [Derive](trait/derive.md) diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index 7a0b4a9ae3..a8c2ae222c 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -1,4 +1,4 @@ -# elision +# Elision Some lifetime patterns are overwelmingly common and so the borrow checker will implicitly add them to save typing and to improve readability. diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index 5f154dba17..917b6b7959 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -1,4 +1,4 @@ -# static +# Static A `'static` lifetime is the longest possible lifetime, and lasts for the lifetime of the running program. A `'static` lifetime may also be From b3f9353e1e6c6e6edb3af562b7c7274b519e4abd Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 27 Mar 2018 17:38:41 +0200 Subject: [PATCH 0798/1122] Rename string conversion page name. --- src/SUMMARY.md | 2 +- src/conversion/string.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 09d9e39f81..5c9cb52cdc 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -36,7 +36,7 @@ - [Conversion](conversion.md) - [From and Into](conversion/from_into.md) - - [To and From String](conversion/string.md) + - [To and from Strings](conversion/string.md) - [Expressions](expression.md) diff --git a/src/conversion/string.md b/src/conversion/string.md index f17794bab2..2d225c917c 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -1,4 +1,4 @@ -# To and From String +# To and from Strings ## `ToString` From 8c54f4ed86d82641167ee24669e5286cfb4fb09f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 28 Mar 2018 13:52:57 +0200 Subject: [PATCH 0799/1122] Fix typo in code comment. Fixes https://github.com/rust-lang/rust-by-example/issues/1032. --- src/std_misc/threads/testcase_mapreduce.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 61fc258c00..4085ea1606 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -116,7 +116,7 @@ fn main() { // we use the "turbofish" ::<> to provide sum() with a type hint. // // TODO: try without the turbofish, by instead explicitly - // specifying the type of intermediate_sums + // specifying the type of final_result let final_result = intermediate_sums.iter().sum::(); println!("Final sum result: {}", final_result); From 6a3fb5cfea0725ad46916c1dfbf3c2c17e78fb96 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 29 Mar 2018 11:02:00 +0200 Subject: [PATCH 0800/1122] Add basic example for TryFrom/TryInto. Fixes https://github.com/rust-lang/rust-by-example/issues/1037. --- src/SUMMARY.md | 5 ++-- src/conversion/try_from_try_into.md | 39 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/conversion/try_from_try_into.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3fd6b2dfa8..63b8dd3ba6 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -35,8 +35,9 @@ - [Aliasing](types/alias.md) - [Conversion](conversion.md) - - [From and Into](conversion/from_into.md) - - [To and from Strings](conversion/string.md) + - [`From` and `Into`](conversion/from_into.md) + - [`TryFrom` and `TryInto`](conversion/try_from_try_into.md) + - [To and from `String`s](conversion/string.md) - [Expressions](expression.md) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md new file mode 100644 index 0000000000..b961eec2b6 --- /dev/null +++ b/src/conversion/try_from_try_into.md @@ -0,0 +1,39 @@ +# `TryFrom` and `TryInto` + +Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are generic traits for converting between types. Unlike `From`/`Into`, the `TryFrom`/`TryInto` traits are used for fallible conversions, and as such, return [`Result`]s. + +[from-into]: conversion/from_into.html +[`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html +[`TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html +[`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html + +```rust +#[derive(Debug, PartialEq)] +struct EvenNumber(i32); + +impl TryFrom for EvenNumber { + type Error = (); + + fn try_from(value: i32) -> Result { + if value % 2 == 0 { + Ok(EvenNumber(value)) + } else { + Err(()) + } + } +} + +fn main() { + // TryFrom + + assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8))); + assert_eq!(EvenNumber::try_from(5), Err(())); + + // TryInto + + let result: Result = 8i32.try_into(); + assert_eq!(result, Ok(EvenNumber(8))); + let result: Result = 5i32.try_into(); + assert_eq!(result, Err(())); +} +``` From f73259f2eaa55798c6f35aada6d6e2fc8de07bfe Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 30 Mar 2018 18:35:24 +0200 Subject: [PATCH 0801/1122] Update lifetime invalid example to actually be invalid. Fixes https://github.com/rust-lang/rust-by-example/issues/1016. --- src/scope/lifetime/fn.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scope/lifetime/fn.md b/src/scope/lifetime/fn.md index ee0c4e7857..64a1f5f7eb 100644 --- a/src/scope/lifetime/fn.md +++ b/src/scope/lifetime/fn.md @@ -33,10 +33,10 @@ fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { // However, the correct lifetime must be returned. fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } -//fn invalid_output<'a>() -> &'a i32 { &7 } +//fn invalid_output<'a>() -> &'a String { &String::from("foo") } // The above is invalid: `'a` must live longer than the function. -// Here, `&7` would create an `i32`, followed by a reference. -// Then the data is dropped upon exiting the scope, leaving +// Here, `&String::from("foo")` would create a `String`, followed by a +// reference. Then the data is dropped upon exiting the scope, leaving // a reference to invalid data to be returned. fn main() { From 04f635d4a6d24aa9c7d4b17be6106630aab71a7c Mon Sep 17 00:00:00 2001 From: Norman Ritchie Date: Sun, 1 Apr 2018 12:54:54 +0300 Subject: [PATCH 0802/1122] Cargo update --- src/cargo/deps.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index c7cc871e39..abcc7816b4 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -9,10 +9,10 @@ To create a new Rust project, ```sh # A binary -cargo new --bin foo +cargo new foo # OR A library -cargo new foo +cargo new --lib foo ``` For the rest of this chapter, I will assume we are making a binary, rather than From 2fc45fe42ee183d34097265f41b52828c12e0cf2 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 3 Apr 2018 11:52:44 -0400 Subject: [PATCH 0803/1122] import TryFrom/TryInto --- src/conversion/try_from_try_into.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md index b961eec2b6..9e3242895b 100644 --- a/src/conversion/try_from_try_into.md +++ b/src/conversion/try_from_try_into.md @@ -1,6 +1,9 @@ # `TryFrom` and `TryInto` -Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are generic traits for converting between types. Unlike `From`/`Into`, the `TryFrom`/`TryInto` traits are used for fallible conversions, and as such, return [`Result`]s. +Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are +generic traits for converting between types. Unlike `From`/`Into`, the +`TryFrom`/`TryInto` traits are used for fallible conversions, and as such, +return [`Result`]s. [from-into]: conversion/from_into.html [`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html @@ -8,6 +11,9 @@ Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are gener [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html ```rust +use std::convert::TryFrom; +use std::convert::TryInto; + #[derive(Debug, PartialEq)] struct EvenNumber(i32); From 8410e965a09f0620cc27e4588538d0652e1b0211 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sun, 8 Apr 2018 09:09:05 -0400 Subject: [PATCH 0804/1122] Update link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2403d504c..8f2479f537 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Learn Rust with examples (Live code editor included) ## Using If you'd like to read Rust by Example, you can visit -[https://rustbyexample.com/](https://rustbyexample.com/) to read it online. +[https://doc.rust-lang.org/stable/rust-by-example/](https://doc.rust-lang.org/stable/rust-by-example/) to read it online. If you'd like to read it locally, [install Rust], and then: From 48925b1200dfc58d7367dc7b6cafeee4ca2a5fe8 Mon Sep 17 00:00:00 2001 From: Severen Redwood Date: Tue, 10 Apr 2018 21:08:37 +1200 Subject: [PATCH 0805/1122] Improve wording around the compiler vs borrow checker Previously it made it seem as if the borrow checker was *the* compiler itself, which while not entirely wrong, isn't as accurate as it could be. The new wording emphasises that the borrow checker is one part of the compiler. --- src/scope/lifetime.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/scope/lifetime.md b/src/scope/lifetime.md index 67c8ea6147..33ffcae71d 100644 --- a/src/scope/lifetime.md +++ b/src/scope/lifetime.md @@ -1,16 +1,16 @@ # Lifetimes -A *lifetime* is a construct the compiler (also called the borrow checker) -uses to ensure all borrows are valid. Specifically, a variable's lifetime -begins when it is created and ends when it is destroyed. While lifetimes -and scopes are often referred to together, they are not the same. +A *lifetime* is a construct the compiler (or more specifically, its *borrow +checker*) uses to ensure all borrows are valid. Specifically, a variable's +lifetime begins when it is created and ends when it is destroyed. While +lifetimes and scopes are often referred to together, they are not the same. -Take, for example, the case where we borrow a variable via `&`. The -borrow has a lifetime that is determined by where it is declared. As a result, -the borrow is valid as long as it ends before the lender is destroyed. However, +Take, for example, the case where we borrow a variable via `&`. The +borrow has a lifetime that is determined by where it is declared. As a result, +the borrow is valid as long as it ends before the lender is destroyed. However, the scope of the borrow is determined by where the reference is used. -In the following example and in the rest of this section, we will see how +In the following example and in the rest of this section, we will see how lifetimes relate to scopes, as well as how the two differ. ```rust,editable From 562eed9bcffcca3b18216ce7e03862fed5b6d247 Mon Sep 17 00:00:00 2001 From: Hugh Wang Date: Fri, 6 Apr 2018 04:58:32 +0000 Subject: [PATCH 0806/1122] Improve links Remove ambiguous "here" in links, and update links that redirect. --- src/cargo.md | 2 +- src/cargo/conventions.md | 7 ++++--- src/cargo/deps.md | 16 ++++++++++------ src/trait/iter.md | 5 +---- src/trait/ops.md | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/cargo.md b/src/cargo.md index d312a53ba4..0f57c13698 100644 --- a/src/cargo.md +++ b/src/cargo.md @@ -9,4 +9,4 @@ useful features to improve code quality and developer velocity! These include - Awareness of benchmarks This chapter will go through some quick basics, but you can find the -comprehensive docs [here](http://doc.crates.io/index.html). +comprehensive docs in [The Cargo Book](https://doc.rust-lang.org/cargo/). diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index 8b613925d2..8f20494db4 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -29,8 +29,9 @@ To tell `cargo` to compile or run this binary as opposed to the default or other binaries, we just pass `cargo` the `--bin my_other_bin` flag, where `my_other_bin` is the name of the binary we want to work with. -In addition to extra binaries, there is support for benchmarks, tests, and -examples. The full capabilities are documented -[here](http://doc.crates.io/book/guide/project-layout.html). +In addition to extra binaries, `cargo` supports [more features] such as +benchmarks, tests, and examples. In the next chapter, we will look more closely at tests. + +[support]: http://doc.crates.io/book/guide/project-layout.html diff --git a/src/cargo/deps.md b/src/cargo/deps.md index abcc7816b4..fd4195f669 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -40,9 +40,6 @@ authors = ["mark"] [dependencies] ``` -You can read more extensively about all of the available configuration options -[here](http://doc.crates.io/manifest.html). - The `name` field under `package` determines the name of the project. This is used by `crates.io` if you publish the crate (more later). It is also the name of the output binary when you compile. @@ -63,9 +60,8 @@ add a dependency to our program, we can simply add the following to our crate clap` in `main.rs`, just like normal. And that's it! You can start using `clap` in your program. -`cargo` also supports other types of dependencies. Here is just a small -sampling. You can find out more -[here](http://doc.crates.io/specifying-dependencies.html). +`cargo` also supports [other types of dependencies][dependencies]. Here is just +a small sampling: ```toml [package] @@ -79,6 +75,10 @@ rand = { git = "https://github.com/rust-lang-nursery/rand" } # from online repo bar = { path = "../bar" } # from a path in the local filesystem ``` +`cargo` is more than a dependency manager. All all of the available +configuration options are listed in the [format specification][manifest] of +`Cargo.toml`. + To build our project we can execute `cargo build` anywhere in the project directory (including subdirectories!). We can also do `cargo run` to build and run. Notice that these commands will resolve all dependencies, download crates @@ -86,3 +86,7 @@ if needed, and build everything, including your crate. (Note that it only rebuilds what it has not already built, similar to `make`). Voila! That's all there is to it! + + +[manifest]: https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html diff --git a/src/trait/iter.md b/src/trait/iter.md index 11758aec3b..558f987999 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -1,6 +1,6 @@ # Iterators -The `Iterator` trait is used to implement iterators over collections such as arrays. +The [`Iterator`][iter] trait is used to implement iterators over collections such as arrays. The trait requires only a method to be defined for the `next` element, which may be manually defined in an `impl` block or automatically @@ -9,9 +9,6 @@ defined (as in arrays and ranges). As a point of convenience for common situations, the `for` construct turns some collections into iterators using the [`.into_iterator()`][intoiter] method. -Methods that can be accessed using the `Iterator` trait in addition -to those shown in the example below can be found [here][iter]. - ```rust,editable struct Fibonacci { curr: u32, diff --git a/src/trait/ops.md b/src/trait/ops.md index b1d38496fc..02e2adf490 100644 --- a/src/trait/ops.md +++ b/src/trait/ops.md @@ -6,7 +6,7 @@ because operators are syntactic sugar for method calls. For example, the `+` ope `a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. -A list of the traits, such as `Add`, that overload operators is available [here][ops]. +A list of the traits, such as `Add`, that overload operators can be found in [`core::ops`][ops]. ```rust,editable use std::ops; From b3d5d9cdce86b645c8f202800cc862b79ba44459 Mon Sep 17 00:00:00 2001 From: Hugh Wang Date: Thu, 12 Apr 2018 12:13:00 +0800 Subject: [PATCH 0807/1122] Fix link --- src/cargo/conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index 8f20494db4..c043b1c809 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -34,4 +34,4 @@ benchmarks, tests, and examples. In the next chapter, we will look more closely at tests. -[support]: http://doc.crates.io/book/guide/project-layout.html +[more features]: https://doc.rust-lang.org/cargo/guide/project-layout.html From 354320d56a30ba18368af490e058dfac912db3b4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 14 Apr 2018 09:14:19 +0900 Subject: [PATCH 0808/1122] Extra 'all'. --- src/cargo/deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index fd4195f669..21db4c2a65 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -75,7 +75,7 @@ rand = { git = "https://github.com/rust-lang-nursery/rand" } # from online repo bar = { path = "../bar" } # from a path in the local filesystem ``` -`cargo` is more than a dependency manager. All all of the available +`cargo` is more than a dependency manager. All of the available configuration options are listed in the [format specification][manifest] of `Cargo.toml`. From 936fb606802c6db8b2bc28dc97538b6be2ad6d38 Mon Sep 17 00:00:00 2001 From: Igor Shaposhnik Date: Tue, 24 Apr 2018 07:22:14 +0300 Subject: [PATCH 0809/1122] Update fn.md fix md syntax --- src/fn.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fn.md b/src/fn.md index 337bf3bc2d..2402d56b8b 100644 --- a/src/fn.md +++ b/src/fn.md @@ -48,3 +48,4 @@ fn fizzbuzz_to(n: u32) { fizzbuzz(n); } } +``` From 2a808e6a3d25a26702a4a4a08568904764ae1bea Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 4 May 2018 18:41:22 -0600 Subject: [PATCH 0810/1122] Remove TryFrom due to destabilization --- src/SUMMARY.md | 1 - src/conversion/try_from_try_into.md | 45 ----------------------------- 2 files changed, 46 deletions(-) delete mode 100644 src/conversion/try_from_try_into.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 63b8dd3ba6..24f7ce8303 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -36,7 +36,6 @@ - [Conversion](conversion.md) - [`From` and `Into`](conversion/from_into.md) - - [`TryFrom` and `TryInto`](conversion/try_from_try_into.md) - [To and from `String`s](conversion/string.md) - [Expressions](expression.md) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md deleted file mode 100644 index 9e3242895b..0000000000 --- a/src/conversion/try_from_try_into.md +++ /dev/null @@ -1,45 +0,0 @@ -# `TryFrom` and `TryInto` - -Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are -generic traits for converting between types. Unlike `From`/`Into`, the -`TryFrom`/`TryInto` traits are used for fallible conversions, and as such, -return [`Result`]s. - -[from-into]: conversion/from_into.html -[`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html -[`TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html -[`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html - -```rust -use std::convert::TryFrom; -use std::convert::TryInto; - -#[derive(Debug, PartialEq)] -struct EvenNumber(i32); - -impl TryFrom for EvenNumber { - type Error = (); - - fn try_from(value: i32) -> Result { - if value % 2 == 0 { - Ok(EvenNumber(value)) - } else { - Err(()) - } - } -} - -fn main() { - // TryFrom - - assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8))); - assert_eq!(EvenNumber::try_from(5), Err(())); - - // TryInto - - let result: Result = 8i32.try_into(); - assert_eq!(result, Ok(EvenNumber(8))); - let result: Result = 5i32.try_into(); - assert_eq!(result, Err(())); -} -``` From e56d61f0d15e2dd1e4093496064935df045e5c25 Mon Sep 17 00:00:00 2001 From: David Alber Date: Sun, 27 May 2018 22:16:13 -0700 Subject: [PATCH 0811/1122] Synchronize Code of Conduct with rust-www --- CODE_OF_CONDUCT.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1a72217d41..d70b2b52ac 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,22 +1,24 @@ # The Rust Code of Conduct +A version of this document [can be found online](https://www.rust-lang.org/conduct.html). + ## Conduct **Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org) -* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. +* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. * On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. * Please be kind and courteous. There's no need to be mean or rude. * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. -* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. -* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. ## Moderation -These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team]. +These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team]. 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. @@ -33,6 +35,6 @@ And if someone takes issue with something you said or did, resist the urge to be The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. -*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/).* +*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* -[Rust moderation team]: https://www.rust-lang.org/en-US/team.html#Moderation-team +[mod_team]: https://www.rust-lang.org/team.html#Moderation-team From c22918a60dd4d30fbb3090580a94d779609df98d Mon Sep 17 00:00:00 2001 From: tyranron Date: Wed, 30 May 2018 18:35:19 +0300 Subject: [PATCH 0812/1122] Add missing i128, u128 primitive types --- src/primitives.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/primitives.md b/src/primitives.md index aa3e3ba18e..14de0d74eb 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -5,8 +5,9 @@ Rust provides access to a wide variety of `primitives`. A sample includes: ### Scalar Types -* signed integers: `i8`, `i16`, `i32`, `i64` and `isize` (pointer size) -* unsigned integers: `u8`, `u16`, `u32`, `u64` and `usize` (pointer size) +* signed integers: `i8`, `i16`, `i32`, `i64`, `i128` and `isize` (pointer size) +* unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128` and `usize` (pointer + size) * floating point: `f32`, `f64` * `char` Unicode scalar values like `'a'`, `'α'` and `'∞'` (4 bytes each) * `bool` either `true` or `false` From 421158afefe1438e34c45f60801d9c8b73d7d5e0 Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 31 May 2018 15:29:02 +0300 Subject: [PATCH 0813/1122] Fix incorrect compiling error of reborrowing in Functions.Closures.Capturing chapter --- src/fn/closures/capture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index 03cdcf67ca..00f500b591 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -47,7 +47,7 @@ fn main() { inc(); inc(); - //let reborrow = &mut count; + //let _reborrow = &mut count; // ^ TODO: try uncommenting this line. // A non-copy type. From d2a64395a5210a61d3512a3a5c615f5c47699443 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 10 May 2018 16:14:01 -0400 Subject: [PATCH 0814/1122] stop travis from deploying --- .travis.yml | 2 -- deploy.sh | 30 ------------------------------ 2 files changed, 32 deletions(-) delete mode 100644 deploy.sh diff --git a/.travis.yml b/.travis.yml index 78e93d6d3a..3ec2b34850 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,5 +20,3 @@ before_script: script: - mdbook build - mdbook test -after_success: - - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index 2c9c6a26fc..0000000000 --- a/deploy.sh +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -# file at the top-level directory of this distribution and at -# http://rust-lang.org/COPYRIGHT. -# -# Licensed under the Apache License, Version 2.0 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - -#!/bin/bash - -rev=$(git rev-parse --short HEAD) - -cd book - -git init -git config user.name "Steve Klabnik" -git config user.email "steve@steveklabnik.com" -git remote add upstream "https://$GITHUB_TOKEN@github.com/rust-lang/rust-by-example.git" -git fetch upstream && git reset upstream/gh-pages - -echo "rustbyexample.com" > CNAME - -touch . - -git add -A . - -git commit -m "rebuild pages at ${rev}" -git push -q upstream HEAD:gh-pages From 730fb72f0cbe4f3c891c512b10ceb71cacce15f7 Mon Sep 17 00:00:00 2001 From: Marwan Al Jubeh Date: Thu, 12 Jul 2018 15:25:08 +0100 Subject: [PATCH 0815/1122] Clarify the result of running the sample code for the wait section This changes the order of the sleep comment and print output to make it match the correct order that those events happen in. Fixes #1088. --- src/std_misc/process/wait.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/std_misc/process/wait.md b/src/std_misc/process/wait.md index 5445ce45fa..ea7dd54a86 100644 --- a/src/std_misc/process/wait.md +++ b/src/std_misc/process/wait.md @@ -16,7 +16,6 @@ fn main() { ```bash $ rustc wait.rs && ./wait +# `wait` keeps running for 5 seconds until the `sleep 5` command finishes reached end of main -# `wait` keeps running for 5 seconds -# `sleep 5` command ends, and then our `wait` program finishes ``` From 75d0345efca1f6bfdd76319fa9e735cc6c67b54d Mon Sep 17 00:00:00 2001 From: Marwan Al Jubeh Date: Fri, 13 Jul 2018 12:43:00 +0100 Subject: [PATCH 0816/1122] Fix a typo in the "Filesystem Operations" section. There is no `std::io::fs` module. --- src/std_misc/fs.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index e41fbcdc8a..42eccf3ef5 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -1,7 +1,6 @@ # Filesystem Operations -The `std::io::fs` module contains several functions that deal with the -filesystem. +The `std::fs` module contains several functions that deal with the filesystem. ```rust,ignore use std::fs; From 76c5375a797f99511c33fae2e89f56742ce5c0c0 Mon Sep 17 00:00:00 2001 From: Marwan Al Jubeh Date: Fri, 13 Jul 2018 15:13:14 +0100 Subject: [PATCH 0817/1122] Fix a broken link to the Rust Cookbook --- src/std_misc/arg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md index f547abfb40..751bf1d98c 100644 --- a/src/std_misc/arg.md +++ b/src/std_misc/arg.md @@ -34,4 +34,4 @@ when creating command-line applications. The [Rust Cookbook] exhibits best practices on how to use one of the more popular command line argument crates, `clap`. -[Rust Cookbook]: https://rust-lang-nursery.github.io/rust-cookbook/app.html#ex-clap-basic +[Rust Cookbook]: https://rust-lang-nursery.github.io/rust-cookbook/cli/arguments.html From d3ef386f2561322ea85f29c86be182eb81f86107 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jul 2018 22:01:26 -0700 Subject: [PATCH 0818/1122] Fix broken link to reference. --- src/error/multiple_error_types/reenter_question_mark.md | 2 +- src/error/multiple_error_types/wrap_error.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index 3cdbbac918..74bcddcca1 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -86,4 +86,4 @@ top level. [`From::from`][from] and [`?`][q_mark] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the--operator +[q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index bdd1dbe220..15c0d662a0 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -91,5 +91,4 @@ for you. [`From::from`][from] and [`Enums`][enums] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the--operator [enums]: custom_types/enum.html From 1a14886ea912f8500b602dcc5ba16210ce70e5ca Mon Sep 17 00:00:00 2001 From: Kevin Wojniak Date: Sun, 29 Jul 2018 13:26:43 -0700 Subject: [PATCH 0819/1122] Fix typo --- src/scope/lifetime/elision.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index a8c2ae222c..f4ba45799f 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -1,6 +1,6 @@ # Elision -Some lifetime patterns are overwelmingly common and so the borrow checker +Some lifetime patterns are overwhelmingly common and so the borrow checker will implicitly add them to save typing and to improve readability. This process of implicit addition is called elision. Elision exists in Rust solely because these patterns are common. From 9bbef9d62c9da26a00c51861569d2954fb3bbc1c Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 9 Aug 2018 23:43:09 +0100 Subject: [PATCH 0820/1122] Added section on compatibility and subsection on raw identifiers. --- src/SUMMARY.md | 7 +++-- src/compatibility.md | 7 +++++ src/compatibility/raw_identifiers.md | 42 ++++++++++++++++++++++++++++ src/index.md | 6 ++-- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/compatibility.md create mode 100644 src/compatibility/raw_identifiers.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 24f7ce8303..31792d0fa7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -196,7 +196,10 @@ - [Integration testing](testing/integration_testing.md) - [Dev-dependencies](testing/dev_dependencies.md) +- [Unsafe Operations](unsafe.md) + +- [Compatibility](compatibility.md) + - [Raw identifiers](compatibility/raw_identifiers.md) + - [Meta](meta.md) - [Documentation](meta/doc.md) - -- [Unsafe Operations](unsafe.md) diff --git a/src/compatibility.md b/src/compatibility.md new file mode 100644 index 0000000000..00424ceb22 --- /dev/null +++ b/src/compatibility.md @@ -0,0 +1,7 @@ +# Compatibility + +The Rust language is fastly evolving, and because of this certain compatibility +issues can arise, despite efforts to ensure forwards-compatibility wherever +possible. + +* [Raw identifiers](compatibility/raw_identifiers.md) diff --git a/src/compatibility/raw_identifiers.md b/src/compatibility/raw_identifiers.md new file mode 100644 index 0000000000..eb42cf645a --- /dev/null +++ b/src/compatibility/raw_identifiers.md @@ -0,0 +1,42 @@ +# Raw identifiers + +Rust, like many programming languages, has the concept of "keywords". +These identifiers mean something to the language, and so you cannot use them in +places like variable names, function names, and other places. +Raw identifiers let you use keywords where they would not normally be allowed. +This is particularly useful when Rust introduces new keywords, and a library +using an older edition of Rust has a variable or function with the same name +as a keyword introduced in a newer edition. + +For example, consider a crate `foo` compiled with the 2015 edition of Rust that +exports a function named `try`. This keyword is reserved for a new feature in +the 2018 edition, so without raw identifiers, we would have no way to name the +function. + +```rust,ignore +extern crate foo; + +fn main() { + foo::try(); +} +``` + +You'll get this error: + +```text +error: expected identifier, found keyword `try` + --> src/main.rs:4:4 + | +4 | foo::try(); + | ^^^ expected identifier, found keyword +``` + +You can write this with a raw identifier: + +```rust,ignore +extern crate foo; + +fn main() { + foo::r#try(); +} +``` diff --git a/src/index.md b/src/index.md index 5f3a1ed613..128b9c0179 100644 --- a/src/index.md +++ b/src/index.md @@ -51,10 +51,12 @@ Now let's begin! - [Testing](testing.html) - All sorts of testing in Rust. -- [Meta](meta.html) - Documentation, Benchmarking. - - [Unsafe Operations](unsafe.html) +- [Compatibility](compatibility.html) + +- [Meta](meta.html) - Documentation, Benchmarking. + [rust]: https://www.rust-lang.org/ [install]: https://www.rust-lang.org/install.html From 8b7402c0cbb198429f78878f9d0377ce7b9df573 Mon Sep 17 00:00:00 2001 From: Jakub Kozlowski Date: Wed, 15 Aug 2018 00:48:24 +0100 Subject: [PATCH 0821/1122] Stabilize macro_vis_matcher --- src/macros/designators.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/macros/designators.md b/src/macros/designators.md index a06d1d41a3..0ff2ed7f87 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -59,3 +59,4 @@ This is a list of all the designators: * `stmt` (*statement*) * `tt` (*token tree*) * `ty` (*type*) +* `vis` (*visibility qualifier*) From 00b203523bf055669c6c19ca1ebef4f1587d80ba Mon Sep 17 00:00:00 2001 From: Lee Date: Wed, 15 Aug 2018 16:21:19 -0400 Subject: [PATCH 0822/1122] Add how to use brace bracket syntax --- src/mod/use.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/mod/use.md b/src/mod/use.md index 9d04b826aa..bfbfc00286 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -1,7 +1,23 @@ # The `use` declaration The `use` declaration can be used to bind a full path to a new name, for easier -access. +access. It is often used like this: + +```rust,editable +extern crate deeply; + +use deeply::nested::{ + my_first_function, + my_second_function, + AndATraitType +}; + +fn main() { + my_first_function(); +} +``` + +Alternatively you can use `as` syntax too: ```rust,editable // Bind the `deeply::nested::function` path to `other_function`. @@ -37,4 +53,4 @@ fn main() { function(); } -``` \ No newline at end of file +``` From 20a2b8dd7de802e3291019da54866913cf6f95e8 Mon Sep 17 00:00:00 2001 From: Julian Gehring Date: Wed, 15 Aug 2018 22:15:44 +0100 Subject: [PATCH 0823/1122] Fix typo in the binding example --- src/flow_control/match/binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index dc6322bb92..9a22503207 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -11,7 +11,7 @@ fn age() -> u32 { } fn main() { - println!("Tell me type of person you are"); + println!("Tell me what type of person you are"); match age() { 0 => println!("I'm not born yet I guess"), From f76773bcd07c4f90a52d06b43da6fd9b6e7e6c12 Mon Sep 17 00:00:00 2001 From: Mukund Lakshman Date: Thu, 16 Aug 2018 13:15:35 -0700 Subject: [PATCH 0824/1122] Fix a race condition in the channels example. Sometimes, `main()` completes before all the threads have finished, so let's explicitly wait for them using `join()` Closes #1099 --- src/std_misc/channels.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/std_misc/channels.md b/src/std_misc/channels.md index e88605543f..3728d5181c 100644 --- a/src/std_misc/channels.md +++ b/src/std_misc/channels.md @@ -16,13 +16,14 @@ fn main() { // where `T` is the type of the message to be transferred // (type annotation is superfluous) let (tx, rx): (Sender, Receiver) = mpsc::channel(); + let mut children = Vec::new(); for id in 0..NTHREADS { // The sender endpoint can be copied let thread_tx = tx.clone(); // Each thread will send its id via the channel - thread::spawn(move || { + let child = thread::spawn(move || { // The thread takes ownership over `thread_tx` // Each thread queues a message in the channel thread_tx.send(id).unwrap(); @@ -31,6 +32,8 @@ fn main() { // immediately after sending its message println!("thread {} finished", id); }); + + children.push(child); } // Here, all the messages are collected @@ -43,5 +46,10 @@ fn main() { // Show the order in which the messages were sent println!("{:?}", ids); + + // Wait for the threads to complete any remaining work + for child in children { + child.join().expect("oops! the child thread panicked"); + } } ``` \ No newline at end of file From f295b40af67eed0158fc3cfcedaa8de3895488b7 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 17 Aug 2018 08:02:40 -0700 Subject: [PATCH 0825/1122] Adjust indentation. --- src/std_misc/channels.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std_misc/channels.md b/src/std_misc/channels.md index 3728d5181c..3f0407afb5 100644 --- a/src/std_misc/channels.md +++ b/src/std_misc/channels.md @@ -49,7 +49,7 @@ fn main() { // Wait for the threads to complete any remaining work for child in children { - child.join().expect("oops! the child thread panicked"); + child.join().expect("oops! the child thread panicked"); } } -``` \ No newline at end of file +``` From 9965da88b0a0586865f66d22e8b75524932eb5f8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 17 Aug 2018 08:05:47 -0700 Subject: [PATCH 0826/1122] Print message order after all other printing has finished. --- src/std_misc/channels.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/std_misc/channels.md b/src/std_misc/channels.md index 3f0407afb5..8c4d45165f 100644 --- a/src/std_misc/channels.md +++ b/src/std_misc/channels.md @@ -43,13 +43,13 @@ fn main() { // `recv` will block the current thread if there are no messages available ids.push(rx.recv()); } - - // Show the order in which the messages were sent - println!("{:?}", ids); - + // Wait for the threads to complete any remaining work for child in children { child.join().expect("oops! the child thread panicked"); } + + // Show the order in which the messages were sent + println!("{:?}", ids); } ``` From 901071f1e4210a1c0930f075682fe66a86e011c7 Mon Sep 17 00:00:00 2001 From: Lee Date: Mon, 27 Aug 2018 18:56:30 -0400 Subject: [PATCH 0827/1122] Add suggestion and hopefully fix build --- src/mod/use.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/use.md b/src/mod/use.md index bfbfc00286..680b65130d 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -4,7 +4,7 @@ The `use` declaration can be used to bind a full path to a new name, for easier access. It is often used like this: ```rust,editable -extern crate deeply; +// extern crate deeply; // normally, this would exist and not be commented out! use deeply::nested::{ my_first_function, @@ -17,7 +17,7 @@ fn main() { } ``` -Alternatively you can use `as` syntax too: +You can use the `as` keyword to bind imports to a different name: ```rust,editable // Bind the `deeply::nested::function` path to `other_function`. From 968bffc07b3b777ac0cfe82ba2f50bda00757765 Mon Sep 17 00:00:00 2001 From: Micooz Date: Sat, 1 Sep 2018 18:01:51 +0800 Subject: [PATCH 0828/1122] Fix comment in array example --- src/primitives/array.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitives/array.md b/src/primitives/array.md index 6c0fda962c..fe4bee94c2 100644 --- a/src/primitives/array.md +++ b/src/primitives/array.md @@ -45,7 +45,7 @@ fn main() { println!("borrow a section of the array as a slice"); analyze_slice(&ys[1 .. 4]); - // Out of bound indexing yields a panic + // Out of bound indexing causes compile error println!("{}", xs[5]); } ``` From 477ff31e1b78a00f116724f4ff3e8cf7bedb149d Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Mon, 3 Sep 2018 16:56:16 +0200 Subject: [PATCH 0829/1122] Improve example for constant variables * `'static` lifetimes are inferred and were removed from the example. * Mention that accessing and modifying static variables is `unsafe`. --- src/custom_types/constants.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/custom_types/constants.md b/src/custom_types/constants.md index 1d1df092a9..5fb868b9b5 100644 --- a/src/custom_types/constants.md +++ b/src/custom_types/constants.md @@ -5,18 +5,13 @@ including global. Both require explicit type annotation: * `const`: An unchangeable value (the common case). * `static`: A possibly `mut`able variable with [`'static`][static] lifetime. - -One special case is the `"string"` literal. It can be assigned directly to a -`static` variable without modification because its type signature: -`&'static str` has the required lifetime of `'static`. All other reference -types must be specifically annotated so that they fulfill the `'static` -lifetime. This may seem minor though because the required explicit annotation -hides the distinction. + The static lifetime is inferred and does not have to be specified. + Accessing or modifying a mutable static variable is [`unsafe`][unsafe]. ```rust,editable,ignore,mdbook-runnable // Globals are declared outside all other scopes. -static LANGUAGE: &'static str = "Rust"; -const THRESHOLD: i32 = 10; +static LANGUAGE: &str = "Rust"; +const THRESHOLD: i32 = 10; fn is_big(n: i32) -> bool { // Access constant in some function @@ -44,3 +39,4 @@ https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md), [`'static` lifetime][static] [static]: scope/lifetime/static_lifetime.html +[unsafe]: unsafe.html From d2b66405ad4b4b4bc2971c4e9eb1b2058ef6e842 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Mon, 3 Sep 2018 17:03:05 +0200 Subject: [PATCH 0830/1122] Update list of unsafe things * Inline assembly is not stable and is thus no longer mentioned. * Mention static mutable variables and unsafe traits instead. --- src/unsafe.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/unsafe.md b/src/unsafe.md index c5143d496f..1ce8e95a23 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -7,10 +7,10 @@ put in place by the compiler; specifically, there are four primary things that unsafe blocks are used for: * dereferencing raw pointers -* calling a function over FFI (but this is covered in [a previous - chapter](std_misc/ffi.html) of the book) -* calling functions which are `unsafe` -* inline assembly +* calling functions or methods which are `unsafe` (including calling a function + over FFI, see [a previous chapter](std_misc/ffi.html) of the book) +* accessing or modifying static mutable variables +* implementing unsafe traits ### Raw Pointers Raw pointers `*` and references `&T` function similarly, but references are From 39cbb06515c1f0762de6290b105a3ea1d73e5080 Mon Sep 17 00:00:00 2001 From: Rahul Singh Date: Tue, 4 Sep 2018 22:30:44 +0530 Subject: [PATCH 0831/1122] update print.md Corrected the typo mistake --- src/hello/print.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index e62da894f8..c8e0006d24 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -7,7 +7,7 @@ some of which include: * `print!`: same as `format!` but the text is printed to the console (io::stdout). * `println!`: same as `print!` but a newline is appended. * `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr). -* `eprintln!`: sames as `eprint!`but a newline is appended. +* `eprintln!`: same as `eprint!`but a newline is appended. All parse text in the same fashion. A plus is that the formatting correctness will be checked at compile time. From 6feca8506f0a0459ecfeb33da3c49dec41b9051a Mon Sep 17 00:00:00 2001 From: Lee Date: Thu, 6 Sep 2018 13:46:05 -0400 Subject: [PATCH 0832/1122] Ignore nonexistent crate --- src/mod/use.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/use.md b/src/mod/use.md index 680b65130d..736aad6bd1 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -3,7 +3,7 @@ The `use` declaration can be used to bind a full path to a new name, for easier access. It is often used like this: -```rust,editable +```rust,editable,ignore // extern crate deeply; // normally, this would exist and not be commented out! use deeply::nested::{ @@ -19,7 +19,7 @@ fn main() { You can use the `as` keyword to bind imports to a different name: -```rust,editable +```rust,editable,ignore // Bind the `deeply::nested::function` path to `other_function`. use deeply::nested::function as other_function; From 1f95397a8127aab3d0148531a4fa909b745460de Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 6 Sep 2018 13:55:46 -0400 Subject: [PATCH 0833/1122] fix a link --- src/compatibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compatibility.md b/src/compatibility.md index 00424ceb22..c756e25d71 100644 --- a/src/compatibility.md +++ b/src/compatibility.md @@ -4,4 +4,4 @@ The Rust language is fastly evolving, and because of this certain compatibility issues can arise, despite efforts to ensure forwards-compatibility wherever possible. -* [Raw identifiers](compatibility/raw_identifiers.md) +* [Raw identifiers](compatibility/raw_identifiers.html) From 01eb5112fce40156a4831a5b28d3c09f178def53 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 11 Sep 2018 16:04:49 +0200 Subject: [PATCH 0834/1122] unsafe: Fix opening paragraph --- src/unsafe.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/unsafe.md b/src/unsafe.md index 1ce8e95a23..e4416796ae 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -2,9 +2,9 @@ As an introduction to this section, to borrow from [the official docs][unsafe], "one should try to minimize the amount of unsafe code in a code base." With that -in mind, let's get started! Unsafe blocks in Rust are used to bypass protections -put in place by the compiler; specifically, there are four primary things that -unsafe blocks are used for: +in mind, let's get started! Unsafe annotations in Rust are used to bypass +protections put in place by the compiler; specifically, there are four primary +things that unsafe is used for: * dereferencing raw pointers * calling functions or methods which are `unsafe` (including calling a function @@ -45,7 +45,7 @@ fn main() { unsafe { let my_slice: &[u32] = slice::from_raw_parts(pointer, length); - + assert_eq!(some_vector.as_slice(), my_slice); } } From 93a4cfb778c0bfafabc3c8bea5a88d5b6df6b299 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Sun, 7 Oct 2018 20:10:58 +1100 Subject: [PATCH 0835/1122] Adding build scripts page. --- src/SUMMARY.md | 1 + src/cargo/build_scripts.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/cargo/build_scripts.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 31792d0fa7..d7169f805e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -87,6 +87,7 @@ - [Dependencies](cargo/deps.md) - [Conventions](cargo/conventions.md) - [Tests](cargo/test.md) + - [Build Scripts](cargo/build_scripts.md) - [Attributes](attribute.md) - [`dead_code`](attribute/unused.md) diff --git a/src/cargo/build_scripts.md b/src/cargo/build_scripts.md new file mode 100644 index 0000000000..ee8184e86a --- /dev/null +++ b/src/cargo/build_scripts.md @@ -0,0 +1,38 @@ +# Build Scripts + +Sometimes a normal build from cargo is not enough. Perhaps your crate needs some +pre-requites before cargo will successfully compile, things like code +generation, or some native code that needs to be compiled. To solve this problem +we have build scripts that Cargo can run. + +To add a build script to your package it can either be specified in the +`Cargo.toml` as follows: + +```toml +[package] +... +build = "build.rs" +``` + +Otherwise Cargo will look for a `build.rs` file in the project directory by +default. + +## How to use a build script + +The build script is simply another Rust file that will be compiled and invoked +prior to compiling anything else in the package. Hence it can be used to fulfil +pre-requisites of your crate. + +Cargo provides the script with inputs via environment variables [specified +here] that can be used. + +The script provides output via stdout. All lines printed are written to +`target/debug/build//output`. Further, lines prefixed with `cargo:` will be +interpreted by Cargo directly and hence can be used to define parameters for the +packages compilation. + +For further specification and examples have a read of the [cargo specification]. + +[specified here]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts + +[cargo specification]: https://doc.rust-lang.org/cargo/reference/build-scripts.html \ No newline at end of file From 890b04d0a520feb83a2260b0d0a032918c11714f Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Mon, 8 Oct 2018 08:13:14 +1100 Subject: [PATCH 0836/1122] Fixing typo. --- src/cargo/build_scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/build_scripts.md b/src/cargo/build_scripts.md index ee8184e86a..c5da00db6a 100644 --- a/src/cargo/build_scripts.md +++ b/src/cargo/build_scripts.md @@ -1,7 +1,7 @@ # Build Scripts Sometimes a normal build from cargo is not enough. Perhaps your crate needs some -pre-requites before cargo will successfully compile, things like code +pre-requisites before cargo will successfully compile, things like code generation, or some native code that needs to be compiled. To solve this problem we have build scripts that Cargo can run. From bae750cb2a86d9be4d05327efc96290862fc51f1 Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Fri, 26 Oct 2018 07:47:48 +1100 Subject: [PATCH 0837/1122] Return Result from main function. --- src/error/result.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/error/result.md b/src/error/result.md index 760003b924..7febd2efe5 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -45,6 +45,39 @@ unpleasant error message. To improve the quality of our error message, we should be more specific about the return type and consider explicitly handling the error. +## Using `Result` in `main` + +The `Result` type can also be the return type of of the `main` function if +specified explicitly. Typically the `main` function will be of the form: + +```rust +fn main() { + println!("Hello World!"); +} +``` + +However `main` is also able to have a return type of `Result`. If an error +occurs within the `main` function it will return an error code and print a debug +representation of the error (using the [`Debug`] trait). The following example +shows such a scenario and touches on aspects covered in [the following section]. + +```rust,editable +use std::num::ParseIntError; + +fn main() -> Result<(), ParseIntError> { + let number_str = "10"; + let number = match number_str.parse::() { + Ok(number) => number, + Err(e) => return Err(e), + }; + println!("{}", number); + Ok(()) +} +``` + + [option]: https://doc.rust-lang.org/std/option/enum.Option.html [result]: https://doc.rust-lang.org/std/result/enum.Result.html [parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse +[`Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html +[the following section]: error/result/early_returns.html From 67164f7b3aca7631eaa085ce579bf5318148000f Mon Sep 17 00:00:00 2001 From: Dylan Maccora Date: Fri, 26 Oct 2018 09:23:31 +1100 Subject: [PATCH 0838/1122] Fixing typo. --- src/error/result.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/result.md b/src/error/result.md index 7febd2efe5..a8d28b9d95 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -47,7 +47,7 @@ about the return type and consider explicitly handling the error. ## Using `Result` in `main` -The `Result` type can also be the return type of of the `main` function if +The `Result` type can also be the return type of the `main` function if specified explicitly. Typically the `main` function will be of the form: ```rust From 636b2897c7908c8047a7215e568337eca3cf8059 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 27 Oct 2018 09:14:07 -0400 Subject: [PATCH 0839/1122] rustfmt example block --- src/error/result.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/error/result.md b/src/error/result.md index a8d28b9d95..1dede872e8 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -67,9 +67,9 @@ use std::num::ParseIntError; fn main() -> Result<(), ParseIntError> { let number_str = "10"; let number = match number_str.parse::() { - Ok(number) => number, - Err(e) => return Err(e), - }; + Ok(number) => number, + Err(e) => return Err(e), + }; println!("{}", number); Ok(()) } From bc1d2f22d9c94784bd91efd966de44415ed4596c Mon Sep 17 00:00:00 2001 From: Nikita Karetnikov Date: Sat, 3 Nov 2018 03:24:27 +0300 Subject: [PATCH 0840/1122] Fix typos --- src/fn/diverging.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fn/diverging.md b/src/fn/diverging.md index d1f3e7bf42..6cd63a0d36 100644 --- a/src/fn/diverging.md +++ b/src/fn/diverging.md @@ -12,7 +12,7 @@ As opposed to all the other types, this one cannot be instantiated, because the set of all possible values this type can have is empty. Note, that it is different from the `()` type, which has exactly one possible value. -For example, this functions returns as usual, although there is no information +For example, this function returns as usual, although there is no information in the return value. ```rust @@ -22,7 +22,7 @@ fn some_fn() { fn main() { let a: () = some_fn(); - println!("This functions returns and you can see this line.") + println!("This function returns and you can see this line.") } ``` From 9622d80239a5b6b95add7d35cbfd0bc40597096b Mon Sep 17 00:00:00 2001 From: Nikita Karetnikov Date: Tue, 6 Nov 2018 10:41:50 +0300 Subject: [PATCH 0841/1122] Remove an extra space character --- src/scope/lifetime/methods.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scope/lifetime/methods.md b/src/scope/lifetime/methods.md index 28588540ba..c7317c833a 100644 --- a/src/scope/lifetime/methods.md +++ b/src/scope/lifetime/methods.md @@ -14,7 +14,7 @@ impl Owner { } fn main() { - let mut owner = Owner(18); + let mut owner = Owner(18); owner.add_one(); owner.print(); @@ -25,4 +25,4 @@ fn main() { [methods] -[methods]: fn/methods.html \ No newline at end of file +[methods]: fn/methods.html From 449f00b51d4cbb548b8c6503c88127fbe3c0bd77 Mon Sep 17 00:00:00 2001 From: Nikita Karetnikov Date: Wed, 7 Nov 2018 16:31:59 +0300 Subject: [PATCH 0842/1122] Remove an extra space character --- src/macros/dry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macros/dry.md b/src/macros/dry.md index 6e765e8469..d3dc2f5871 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -10,7 +10,7 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for // operators and tokens. - ($a:ident, $b: ident, $func:ident, $op:tt) => ( + ($a:ident, $b:ident, $func:ident, $op:tt) => ( assert!($a.len() == $b.len(), "{:?}: dimension mismatch: {:?} {:?} {:?}", stringify!($func), @@ -41,7 +41,7 @@ op!(sub_assign, Sub, -=, sub); mod test { use std::iter; macro_rules! test { - ($func: ident, $x:expr, $y:expr, $z:expr) => { + ($func:ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { for size in 0usize..10 { From bb6fb9ebd728a42c605b8164846eb41321e0e6f5 Mon Sep 17 00:00:00 2001 From: Nikita Karetnikov Date: Wed, 7 Nov 2018 16:57:54 +0300 Subject: [PATCH 0843/1122] Reformat the comment to match the rest of the file --- src/macros/dry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros/dry.md b/src/macros/dry.md index d3dc2f5871..ffa8250687 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -57,7 +57,7 @@ mod test { } } - // Test `add_assign`, `mul_assign` and `sub_assign` + // Test `add_assign`, `mul_assign`, and `sub_assign`. test!(add_assign, 1u32, 2u32, 3u32); test!(mul_assign, 2u32, 3u32, 6u32); test!(sub_assign, 3u32, 2u32, 1u32); From 81739b4709cda6b699ffc8330962c88cac8c416b Mon Sep 17 00:00:00 2001 From: Nikita Karetnikov Date: Thu, 8 Nov 2018 14:21:39 +0300 Subject: [PATCH 0844/1122] Add a comment about curly braces --- src/macros/dsl.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/macros/dsl.md b/src/macros/dsl.md index 1182b97cc7..de28910cd0 100644 --- a/src/macros/dsl.md +++ b/src/macros/dsl.md @@ -39,3 +39,6 @@ Output: This was a very simple example, but much more complex interfaces have been developed, such as [`lazy_static`](https://crates.io/crates/lazy_static) or [`clap`](https://crates.io/crates/clap). + +Also, note the two pairs of braces in the macro. The outer ones are +part of the syntax of `macro_rules!`, in addition to `()` or `[]`. From 4d5e29321ce7080e982c7faa622ab92f859b4ed3 Mon Sep 17 00:00:00 2001 From: Jason Liquorish Date: Tue, 13 Nov 2018 20:05:48 +0000 Subject: [PATCH 0845/1122] Make code editable --- src/trait/derive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/derive.md b/src/trait/derive.md index 465eed2683..a1b0ad8f12 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -13,7 +13,7 @@ The following is a list of derivable traits: * [`Default`][default], to create an empty instance of a data type. * [`Debug`][debug], to format a value using the `{:?}` formatter. -```rust,example +```rust,editable // `Centimeters`, a tuple struct that can be compared #[derive(PartialEq, PartialOrd)] struct Centimeters(f64); From 55d4e9cc18d233f91538bb7cc664f4b42f156c22 Mon Sep 17 00:00:00 2001 From: Joe Van Dyk Date: Tue, 13 Nov 2018 21:35:26 -0800 Subject: [PATCH 0846/1122] Install the right version of mdbook --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f2479f537..7b4b80f63b 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ If you'd like to read it locally, [install Rust], and then: ```bash $ git clone https://github.com/rust-lang/rust-by-example $ cd rust-by-example -$ cargo install mdbook +$ cargo install mdbook --version ^0.1 --force $ mdbook build $ mdbook serve ``` From 2ce92beabb912d417a7314d6da83ac9b50dc2afb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 10:10:23 -0500 Subject: [PATCH 0847/1122] fix up for mdbook 0.2 --- README.md | 2 +- theme/index.hbs | 184 ------------------------------------------------ 2 files changed, 1 insertion(+), 185 deletions(-) delete mode 100644 theme/index.hbs diff --git a/README.md b/README.md index 7b4b80f63b..858efc2201 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ If you'd like to read it locally, [install Rust], and then: ```bash $ git clone https://github.com/rust-lang/rust-by-example $ cd rust-by-example -$ cargo install mdbook --version ^0.1 --force +$ cargo install mdbook --version ^0.2 --force $ mdbook build $ mdbook serve ``` diff --git a/theme/index.hbs b/theme/index.hbs deleted file mode 100644 index 89dfaaa45b..0000000000 --- a/theme/index.hbs +++ /dev/null @@ -1,184 +0,0 @@ - - - - - {{ title }} - - - - - - - - - - - - - - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - - - - - - - - - - - - - - {{#each additional_js}} - - {{/each}} - - - - - - - - - - - -
- -
- - -
- {{{ content }}} -
- - - {{#previous}} - - {{/previous}} - - {{#next}} - - {{/next}} - -
- - {{#previous}} - - {{/previous}} - - {{#next}} - - {{/next}} - -
- - - - - - - {{{livereload}}} - - {{#if google_analytics}} - - {{/if}} - - {{#if playpens_editable}} - - - - - - {{/if}} - - {{#if is_print}} - - {{/if}} - - - - - From 097a5eb020aa716336ec1ea8477964a6860be469 Mon Sep 17 00:00:00 2001 From: Mike Cluck Date: Tue, 20 Nov 2018 14:37:51 -0700 Subject: [PATCH 0848/1122] Fixes #1115 by correcting the typo from into_iterator to into_iter --- src/trait/iter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/iter.md b/src/trait/iter.md index 558f987999..91f65a53cc 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -7,7 +7,7 @@ which may be manually defined in an `impl` block or automatically defined (as in arrays and ranges). As a point of convenience for common situations, the `for` construct -turns some collections into iterators using the [`.into_iterator()`][intoiter] method. +turns some collections into iterators using the [`.into_iter()`][intoiter] method. ```rust,editable struct Fibonacci { From c1aa8b77d5eb14e2504de06445e5a16febaad55c Mon Sep 17 00:00:00 2001 From: Poulad Ashrafpour <14295804+poulad@users.noreply.github.com> Date: Wed, 28 Nov 2018 22:16:33 -0500 Subject: [PATCH 0849/1122] Edit a typo --- src/flow_control/match/destructuring/destructure_pointers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/match/destructuring/destructure_pointers.md b/src/flow_control/match/destructuring/destructure_pointers.md index 9f2ab60e42..d92ba22be8 100644 --- a/src/flow_control/match/destructuring/destructure_pointers.md +++ b/src/flow_control/match/destructuring/destructure_pointers.md @@ -14,7 +14,7 @@ fn main() { let reference = &4; match reference { - // If `reference`s is pattern matched against `&val`, it results + // If `reference` is pattern matched against `&val`, it results // in a comparison like: // `&i32` // `&val` @@ -58,4 +58,4 @@ fn main() { }, } } -``` \ No newline at end of file +``` From c8b58dbd55094559397a3e74786c8901a37f15f4 Mon Sep 17 00:00:00 2001 From: Mike Cluck Date: Thu, 29 Nov 2018 09:40:59 -0700 Subject: [PATCH 0850/1122] Converted println braces to more conventional parentheses --- src/conversion/string.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conversion/string.md b/src/conversion/string.md index 2d225c917c..6073d05a35 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -42,7 +42,7 @@ fn main() { let turbo_parsed = "10".parse::().unwrap(); let sum = parsed + turbo_parsed; - println!{"Sum: {:?}", sum}; + println!("Sum: {:?}", sum); } ``` From 3a0a45e57247bd3c3386fc3bb0ca05e3008d87a0 Mon Sep 17 00:00:00 2001 From: Poulad Ashrafpour <14295804+poulad@users.noreply.github.com> Date: Mon, 3 Dec 2018 21:50:44 -0500 Subject: [PATCH 0851/1122] Update conventions.md --- src/cargo/conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/conventions.md b/src/cargo/conventions.md index c043b1c809..6e8196608e 100644 --- a/src/cargo/conventions.md +++ b/src/cargo/conventions.md @@ -12,7 +12,7 @@ foo Suppose that we wanted to have two binaries in the same project, though. What then? -It turns out that `cargo` supports this. The default binary name is `main.rs`, as +It turns out that `cargo` supports this. The default binary name is `main`, as we saw before, but you can add additional binaries by placing them in a `bin/` directory: From 37e58e60de4ed21bfe48498c537322d4e56b7e73 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 10 Dec 2018 09:19:54 -0800 Subject: [PATCH 0852/1122] The code of conduct link was dead. I fixed it. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f8d5e43a74..70d908f0bc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ better! We'd love to have your contribution. We expect all contributors to abide by the [Rust code of conduct], which you can find at that link or in the [`CODE_OF_CONDUCT.md`] file in this repository. -[Rust code of conduct]: https://www.rust-lang.org/en-US/conduct.html +[Rust code of conduct]: https://www.rust-lang.org/policies/code-of-conduct [`CODE_OF_CONDUCT.md`]: https://github.com/rust-lang/rust-by-example/blob/master/CODE_OF_CONDUCT.md ## License From a8ffdd47d7d2d151501bff03bee460736ba2d6cb Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 10 Dec 2018 09:23:40 -0800 Subject: [PATCH 0853/1122] I added a space in the Display fmt for Complex --- src/hello/print/print_display.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 5bf4460514..dc86ff2edf 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -112,7 +112,7 @@ guide to add a Complex struct to the example. When printed in the same way, the output should be: ```txt -Display: 3.3 +7.2i +Display: 3.3 + 7.2i Debug: Complex { real: 3.3, imag: 7.2 } ``` From 83faec6a8239a342aa86fd9e8e70db0f1705d8b4 Mon Sep 17 00:00:00 2001 From: sergio valverde Date: Mon, 10 Dec 2018 11:45:58 -0600 Subject: [PATCH 0854/1122] Fix Rust install link in the index --- src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.md b/src/index.md index 128b9c0179..f83efcdfe1 100644 --- a/src/index.md +++ b/src/index.md @@ -59,6 +59,6 @@ Now let's begin! [rust]: https://www.rust-lang.org/ -[install]: https://www.rust-lang.org/install.html +[install]: https://www.rust-lang.org/tools/install [std]: https://doc.rust-lang.org/std/ [home]: https://github.com/rust-lang/rust-by-example From e1655a033ba64550a70ad09e5ab8f6d929fa3fdd Mon Sep 17 00:00:00 2001 From: Marcus Stollsteimer Date: Fri, 14 Dec 2018 15:25:31 +0100 Subject: [PATCH 0855/1122] Fix typo --- src/testing/doc_testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index 5246ecba9a..f25ffab285 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -68,7 +68,7 @@ test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Motivation behind documentation tests -The main purpose of documentation tests is to serve as an examples that exercise +The main purpose of documentation tests is to serve as examples that exercise the functionality, which is one of the most important [guidelines][question-instead-of-unwrap]. It allows using examples from docs as complete code snippets. But using `?` makes compilation fail since `main` From 73141dd1799949a3d582ec4979a102e90ceb5202 Mon Sep 17 00:00:00 2001 From: 515hikaru <12kojima.takahiro@gmail.com> Date: Sat, 15 Dec 2018 22:23:05 +0900 Subject: [PATCH 0856/1122] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 858efc2201..a1a9033f9e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ If you'd like to read it locally, [install Rust], and then: ```bash $ git clone https://github.com/rust-lang/rust-by-example $ cd rust-by-example -$ cargo install mdbook --version ^0.2 --force +$ cargo install mdbook --version 0.2 --force $ mdbook build $ mdbook serve ``` From 6150bf7ddc7a7a74996328b6cf04692031d413b8 Mon Sep 17 00:00:00 2001 From: Bart Smykla Date: Sun, 16 Dec 2018 09:43:03 +0100 Subject: [PATCH 0857/1122] Fixed small logic error in error/option_unwrap/and_then To know about ingredients, you need to know recipe first. Signed-off-by: Bart Smykla --- src/error/option_unwrap/and_then.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/error/option_unwrap/and_then.md b/src/error/option_unwrap/and_then.md index aab95cac30..99d8133ac6 100644 --- a/src/error/option_unwrap/and_then.md +++ b/src/error/option_unwrap/and_then.md @@ -34,12 +34,12 @@ fn have_recipe(food: Food) -> Option { } } -// To make a dish, we need both the ingredients and the recipe. +// To make a dish, we need both the recipe and the ingredients. // We can represent the logic with a chain of `match`es: fn cookable_v1(food: Food) -> Option { - match have_ingredients(food) { + match have_recipe(food) { None => None, - Some(food) => match have_recipe(food) { + Some(food) => match have_ingredients(food) { None => None, Some(food) => Some(food), }, @@ -48,7 +48,7 @@ fn cookable_v1(food: Food) -> Option { // This can conveniently be rewritten more compactly with `and_then()`: fn cookable_v2(food: Food) -> Option { - have_ingredients(food).and_then(have_recipe) + have_recipe(food).and_then(have_ingredients) } fn eat(food: Food, day: Day) { From 6e903a2fe08a7aca7ef3635ae1586be1e37c1596 Mon Sep 17 00:00:00 2001 From: Bart Smykla Date: Sun, 16 Dec 2018 17:11:08 +0100 Subject: [PATCH 0858/1122] Added two missing backticks in generics/multi_bounds Just small fix, adding two missing backticks in generics/multi_bounds Signed-off-by: Bart Smykla --- src/generics/multi_bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md index 9c1dfb6680..c563282bcb 100644 --- a/src/generics/multi_bounds.md +++ b/src/generics/multi_bounds.md @@ -12,8 +12,8 @@ fn compare_prints(t: &T) { } fn compare_types(t: &T, u: &U) { - println!("t: `{:?}", t); - println!("u: `{:?}", u); + println!("t: `{:?}`", t); + println!("u: `{:?}`", u); } fn main() { From d558f46e2d18001bc2ee03e2fabf13c03b93359c Mon Sep 17 00:00:00 2001 From: Bart Smykla Date: Wed, 19 Dec 2018 12:35:39 +0100 Subject: [PATCH 0859/1122] Changed word `function` to `type` in comment of fn area Closes #1130 Function area is taking generic type instead of function, so word `type` is correct in that scenario as suggested by @steveklabnik in issue #1130 Signed-off-by: Bart Smykla --- src/generics/bounds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics/bounds.md b/src/generics/bounds.md index dbe4e7fa04..ca9496013c 100644 --- a/src/generics/bounds.md +++ b/src/generics/bounds.md @@ -49,7 +49,7 @@ fn print_debug(t: &T) { println!("{:?}", t); } -// `T` must implement `HasArea`. Any function which meets +// `T` must implement `HasArea`. Any type which meets // the bound can access `HasArea`'s function `area`. fn area(t: &T) -> f64 { t.area() } From ec72961e710a004c51550a500aacec572ee02983 Mon Sep 17 00:00:00 2001 From: Speedy Consoles Date: Thu, 20 Dec 2018 17:25:20 +0100 Subject: [PATCH 0860/1122] Clarify pub(restricted) example a bit --- src/mod/visibility.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/mod/visibility.md b/src/mod/visibility.md index 6345630108..8e952fe48a 100644 --- a/src/mod/visibility.md +++ b/src/mod/visibility.md @@ -43,7 +43,7 @@ mod my_mod { } // Functions declared using `pub(self)` syntax are only visible within - // the current module + // the current module, which is the same as leaving them private pub(self) fn public_function_in_nested() { println!("called `my_mod::nested::public_function_in_nested"); } @@ -73,6 +73,13 @@ mod my_mod { pub fn function() { println!("called `my_mod::private_nested::function()`"); } + + // Private parent items will still restrict the visibility of a child item, + // even if it is declared as visible within a bigger scope. + #[allow(dead_code)] + pub(crate) fn restricted_function() { + println!("called `my_mod::private_nested::restricted_function()`"); + } } } @@ -113,5 +120,9 @@ fn main() { // Error! `private_nested` is a private module //my_mod::private_nested::function(); // TODO ^ Try uncommenting this line + + // Error! `private_nested` is a private module + //my_mod::private_nested::restricted_function(); + // TODO ^ Try uncommenting this line } -``` \ No newline at end of file +``` From 26b6c3642622156035cfa5ced4db9b072407e999 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Sun, 23 Dec 2018 09:54:56 -0500 Subject: [PATCH 0861/1122] Update syntax for 2018 Edition Under the 2018 Edition, the `crate::` namespace is required when `use` is employed to reference a structure created in the current module. Without `crate::` this example will not compile under the 2018 Edition; with this change, the example complies again. --- src/custom_types/enum/enum_use.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/custom_types/enum/enum_use.md b/src/custom_types/enum/enum_use.md index 01eb99cbc7..a6ac21a9b2 100644 --- a/src/custom_types/enum/enum_use.md +++ b/src/custom_types/enum/enum_use.md @@ -19,9 +19,9 @@ enum Work { fn main() { // Explicitly `use` each name so they are available without // manual scoping. - use Status::{Poor, Rich}; + use crate::Status::{Poor, Rich}; // Automatically `use` each name inside `Work`. - use Work::*; + use crate::Work::*; // Equivalent to `Status::Poor`. let status = Poor; From 4cab400b4d15b34756a76605be9ed90f0d0b801c Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Sun, 23 Dec 2018 10:19:53 -0500 Subject: [PATCH 0862/1122] Update linked list to 2018 Edition syntax --- src/custom_types/enum/testcase_linked_list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index 3c10ed61c2..3a400ccc08 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -3,7 +3,7 @@ A common use for `enums` is to create a linked-list: ```rust,editable -use List::*; +crate::use List::*; enum List { // Cons: Tuple struct that wraps an element and a pointer to the next node From 2ea8fb2b41dcf6ec7ca66059a2325fa722a3f606 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Sun, 23 Dec 2018 14:15:43 -0500 Subject: [PATCH 0863/1122] Fix syntax error with use statement --- src/custom_types/enum/testcase_linked_list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index 3a400ccc08..61109d1596 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -3,7 +3,7 @@ A common use for `enums` is to create a linked-list: ```rust,editable -crate::use List::*; +use crate::List::*; enum List { // Cons: Tuple struct that wraps an element and a pointer to the next node From b919141218b27a90c78495b4bef7895c8bf4c121 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Wed, 26 Dec 2018 11:06:56 -0500 Subject: [PATCH 0864/1122] Update visibility subchapter to 2018 syntax --- src/mod/visibility.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/visibility.md b/src/mod/visibility.md index 6345630108..5f436f57da 100644 --- a/src/mod/visibility.md +++ b/src/mod/visibility.md @@ -37,7 +37,7 @@ mod my_mod { // Functions declared using `pub(in path)` syntax are only visible // within the given path. `path` must be a parent or ancestor module - pub(in my_mod) fn public_function_in_my_mod() { + pub(in crate::my_mod) fn public_function_in_my_mod() { print!("called `my_mod::nested::public_function_in_my_mod()`, that\n > "); public_function_in_nested() } @@ -114,4 +114,4 @@ fn main() { //my_mod::private_nested::function(); // TODO ^ Try uncommenting this line } -``` \ No newline at end of file +``` From 45d1e66415a63a4e37b1967b34fea605a8f6a843 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Wed, 26 Dec 2018 11:17:02 -0500 Subject: [PATCH 0865/1122] Update "use" subchapter to 2018 Edition syntax --- src/mod/super.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/super.md b/src/mod/super.md index c0088808be..038d4b1271 100644 --- a/src/mod/super.md +++ b/src/mod/super.md @@ -44,7 +44,7 @@ mod my { // This will bind to the `cool::function` in the *crate* scope. // In this case the crate scope is the outermost scope. { - use cool::function as root_function; + use crate::cool::function as root_function; root_function(); } } @@ -53,4 +53,4 @@ mod my { fn main() { my::indirect_call(); } -``` \ No newline at end of file +``` From da6b75014b391cbdf8f75d9f53607f727db64862 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Wed, 26 Dec 2018 11:17:48 -0500 Subject: [PATCH 0866/1122] Update "use" subchapter to 2018 Edition syntax --- src/mod/use.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/use.md b/src/mod/use.md index 736aad6bd1..5f99138726 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -6,7 +6,7 @@ access. It is often used like this: ```rust,editable,ignore // extern crate deeply; // normally, this would exist and not be commented out! -use deeply::nested::{ +use crate::deeply::nested::{ my_first_function, my_second_function, AndATraitType @@ -43,7 +43,7 @@ fn main() { { // This is equivalent to `use deeply::nested::function as function`. // This `function()` will shadow the outer one. - use deeply::nested::function; + use crate::deeply::nested::function; function(); // `use` bindings have a local scope. In this case, the From d76a8ef5d1853a41c786afc53c4b56889c6c7b95 Mon Sep 17 00:00:00 2001 From: Bart Smykla Date: Sun, 30 Dec 2018 19:28:00 +0000 Subject: [PATCH 0867/1122] Added two missing full stops In listing of derivable traits, two of the list items didn't have full stop at the end, like the other items. Signed-off-by: Bart Smykla --- src/trait/derive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trait/derive.md b/src/trait/derive.md index a1b0ad8f12..ff37bffc67 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -6,9 +6,9 @@ manually implemented if a more complex behavior is required. The following is a list of derivable traits: * Comparison traits: - [`Eq`][eq], [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord] + [`Eq`][eq], [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord]. * [`Clone`][clone], to create `T` from `&T` via a copy. -* [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics' +* [`Copy`][copy], to give a type 'copy semantics' instead of 'move semantics'. * [`Hash`][hash], to compute a hash from `&T`. * [`Default`][default], to create an empty instance of a data type. * [`Debug`][debug], to format a value using the `{:?}` formatter. From 4fbafbb682aa66e667a1fb1ca6cb7387d6ea6235 Mon Sep 17 00:00:00 2001 From: Bart Smykla Date: Mon, 31 Dec 2018 17:06:04 +0000 Subject: [PATCH 0868/1122] Removed unnecessary spaces before macro designators in macros/dry In other places there is no space before designators so I removed unnecessary spaces in two places to make it more consistent. Signed-off-by: Bart Smykla --- src/macros/dry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macros/dry.md b/src/macros/dry.md index 6e765e8469..d3dc2f5871 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -10,7 +10,7 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for // operators and tokens. - ($a:ident, $b: ident, $func:ident, $op:tt) => ( + ($a:ident, $b:ident, $func:ident, $op:tt) => ( assert!($a.len() == $b.len(), "{:?}: dimension mismatch: {:?} {:?} {:?}", stringify!($func), @@ -41,7 +41,7 @@ op!(sub_assign, Sub, -=, sub); mod test { use std::iter; macro_rules! test { - ($func: ident, $x:expr, $y:expr, $z:expr) => { + ($func:ident, $x:expr, $y:expr, $z:expr) => { #[test] fn $func() { for size in 0usize..10 { From c9956cea628365c4621628674c10930653102f20 Mon Sep 17 00:00:00 2001 From: Leon George Date: Wed, 16 Jan 2019 11:43:37 +0100 Subject: [PATCH 0869/1122] fix typo --- src/flow_control/for.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index f4d5672ab6..4205b002c4 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -108,7 +108,7 @@ fn main() { ``` In the above snippets note the type of `match` branch, that is the key -difference in the types or iteration. The difference in type then of course +difference in the types of iteration. The difference in type then of course implies differing actions that are able to be performed. ### See also From 6c5bd9c833a6011b70faa2f9f78956bea9d3db71 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 16 Jan 2019 23:36:01 +0700 Subject: [PATCH 0870/1122] Use new book links instead of the old with second-edition ones --- src/cargo/test.md | 2 +- src/error.md | 2 +- src/error/multiple_error_types/boxing_errors.md | 2 +- src/scope/lifetime/elision.md | 2 +- src/std_misc/threads/testcase_mapreduce.md | 4 ++-- src/testing.md | 2 +- src/trait/ops.md | 2 +- src/unsafe.md | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 933c6c5e4a..b5ace3c6f9 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -2,7 +2,7 @@ As we know testing is integral to any piece of software! Rust has first-class support for unit and integration testing ([see this -chapter](https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html) in +chapter](https://doc.rust-lang.org/book/ch11-00-testing.html) in TRPL). From the testing chapters linked above, we see how to write unit tests and diff --git a/src/error.md b/src/error.md index ee81f7ca00..ea6c1b17ff 100644 --- a/src/error.md +++ b/src/error.md @@ -28,4 +28,4 @@ do that unless it's a test or quick prototype). For a more rigorous discussion of error handling, refer to the error handling section in the [official book][book]. -[book]: https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html +[book]: https://doc.rust-lang.org/book/ch09-00-error-handling.html diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index c5f43a9332..10d02ea27e 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -67,6 +67,6 @@ fn main() { [Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] [box]: https://doc.rust-lang.org/std/boxed/struct.Box.html -[dynamic_dispatch]: https://doc.rust-lang.org/book/second-edition/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch +[dynamic_dispatch]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch [error]: https://doc.rust-lang.org/std/error/trait.Error.html [from]: https://doc.rust-lang.org/std/convert/trait.From.html diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index f4ba45799f..9a7204b25d 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -40,4 +40,4 @@ fn main() { [elision][elision] -[elision]: https://doc.rust-lang.org/book/second-edition/ch10-03-lifetime-syntax.html#lifetime-elision +[elision]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 4085ea1606..6de19e0931 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -143,10 +143,10 @@ defined by a static constant at the beginning of the program. [thread]: std_misc/threads.html [vectors]: std/vec.html [iterators]: trait/iter.html -[destructuring]: https://doc.rust-lang.org/book/second-edition/ch18-03-pattern-syntax.html#destructuring-to-break-apart-values +[destructuring]: https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html#destructuring-to-break-apart-values [closures]: fn/closures.html [move]: scope/move.html -[move_closure]: https://doc.rust-lang.org/book/second-edition/ch13-01-closures.html#closures-can-capture-their-environment +[move_closure]: https://doc.rust-lang.org/book/ch13-01-closures.html#closures-can-capture-their-environment [turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect [unwrap]: error/option_unwrap.html [enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate diff --git a/src/testing.md b/src/testing.md index 24c7a24381..b94462474e 100644 --- a/src/testing.md +++ b/src/testing.md @@ -22,5 +22,5 @@ Also Rust has support for specifying additional dependencies for tests: [doc]: testing/doc_testing.html [integration]: testing/integration_testing.html [dev-dependencies]: testing/dev_dependencies.html -[doc-testing]: https://doc.rust-lang.org/book/second-edition/ch11-00-testing.html +[doc-testing]: https://doc.rust-lang.org/book/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/trait/ops.md b/src/trait/ops.md index 02e2adf490..3d4aa3bc8e 100644 --- a/src/trait/ops.md +++ b/src/trait/ops.md @@ -58,4 +58,4 @@ fn main() { [add]: https://doc.rust-lang.org/core/ops/trait.Add.html [ops]: https://doc.rust-lang.org/core/ops/ -[syntax]:https://doc.rust-lang.org/book/second-edition/appendix-02-operators.html +[syntax]:https://doc.rust-lang.org/book/appendix-02-operators.html diff --git a/src/unsafe.md b/src/unsafe.md index e4416796ae..742762c279 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -57,5 +57,5 @@ is of the correct type. If these invariants aren't upheld then the program's behaviour is undefined and there is no knowing what will happen. -[unsafe]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html +[unsafe]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html [`std::slice::from_raw_parts`]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html From bfb45567d2093e9a820b678b77fc395898bfca4e Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 17 Jan 2019 10:58:55 +0700 Subject: [PATCH 0871/1122] Remove unused import and format with `rustfmt` --- .../multiple_error_types/define_error_type.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/error/multiple_error_types/define_error_type.md b/src/error/multiple_error_types/define_error_type.md index fdd9e80b00..b7187d0d01 100644 --- a/src/error/multiple_error_types/define_error_type.md +++ b/src/error/multiple_error_types/define_error_type.md @@ -18,14 +18,13 @@ Rust allows us to define our own error types. In general, a "good" error type: ```rust,editable use std::error; use std::fmt; -use std::num::ParseIntError; type Result = std::result::Result; -#[derive(Debug, Clone)] // Define our error types. These may be customized for our error handling cases. // Now we will be able to write our own errors, defer to an underlying error // implementation, or do something in between. +#[derive(Debug, Clone)] struct DoubleError; // Generation of an error is completely separate from how it is displayed. @@ -53,17 +52,19 @@ impl error::Error for DoubleError { fn double_first(vec: Vec<&str>) -> Result { vec.first() - // Change the error to our new type. - .ok_or(DoubleError) - .and_then(|s| s.parse::() - // Update to the new error type here also. - .map_err(|_| DoubleError) - .map(|i| 2 * i)) + // Change the error to our new type. + .ok_or(DoubleError) + .and_then(|s| { + s.parse::() + // Update to the new error type here also. + .map_err(|_| DoubleError) + .map(|i| 2 * i) + }) } fn print(result: Result) { match result { - Ok(n) => println!("The first doubled is {}", n), + Ok(n) => println!("The first doubled is {}", n), Err(e) => println!("Error: {}", e), } } From 9f8d3a294ec22cb470463473f0458f8c9be0c43b Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 17 Jan 2019 11:47:15 +0700 Subject: [PATCH 0872/1122] Remove unused import and rustfmt --- src/error/multiple_error_types/boxing_errors.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index c5f43a9332..aceafd6dd2 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -11,7 +11,6 @@ via [`From`][from]. ```rust,editable use std::error; use std::fmt; -use std::num::ParseIntError; // Change the alias to `Box`. type Result = std::result::Result>; @@ -38,15 +37,17 @@ impl error::Error for EmptyVec { fn double_first(vec: Vec<&str>) -> Result { vec.first() - .ok_or_else(|| EmptyVec.into()) // Converts to Box - .and_then(|s| s.parse::() - .map_err(|e| e.into()) // Converts to Box - .map(|i| 2 * i)) + .ok_or_else(|| EmptyVec.into()) // Converts to Box + .and_then(|s| { + s.parse::() + .map_err(|e| e.into()) // Converts to Box + .map(|i| 2 * i) + }) } fn print(result: Result) { match result { - Ok(n) => println!("The first doubled is {}", n), + Ok(n) => println!("The first doubled is {}", n), Err(e) => println!("Error: {}", e), } } From 1ee32b37922126ee19654c642dc4a3e7bc22a2a6 Mon Sep 17 00:00:00 2001 From: Janus Date: Thu, 17 Jan 2019 10:50:24 +0100 Subject: [PATCH 0873/1122] Recommend implementing Display over ToString Resolves #1131. --- src/conversion/string.md | 18 +++++++++++------- src/hello/print.md | 5 +++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/conversion/string.md b/src/conversion/string.md index 6073d05a35..82101b8679 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -1,20 +1,22 @@ # To and from Strings -## `ToString` +## Converting to String -To convert any type to a `String` it is as simple as implementing the [`ToString`] -trait for the type. +To convert any type to a `String` is as simple as implementing the [`ToString`] +trait for the type. Rather than doing so directly, you should implement the +[`fmt::Display`][Display] trait which automagically provides [`ToString`] and +also allows printing the type as discussed in the section on [`print!`][print]. ```rust,editable -use std::string::ToString; +use std::fmt; struct Circle { radius: i32 } -impl ToString for Circle { - fn to_string(&self) -> String { - format!("Circle of radius {:?}", self.radius) +impl fmt::Display for Circle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Circle of radius {}", self.radius) } } @@ -47,5 +49,7 @@ fn main() { ``` [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html +[Display]: https://doc.rust-lang.org/std/fmt/trait.Display.html +[print]: /hello/print.html [`parse`]: https://doc.rust-lang.org/std/primitive.str.html#method.parse [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html diff --git a/src/hello/print.md b/src/hello/print.md index c8e0006d24..e91ee64bcf 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -67,6 +67,9 @@ friendly fashion. Here, `fmt::Display` was used because the std library provides implementations for these types. To print text for custom types, more steps are required. +Implementing the `fmt::Display` trait automagically implements the +[`ToString`] trait which allows us to [convert] the type to [`String`][string]. + ### Activities * Fix the two issues in the above code (see FIXME) so that it runs without @@ -87,3 +90,5 @@ and [`traits`][traits] [string]: std/str.html [structs]: custom_types/structs.html [traits]: trait.html +[`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html +[convert]: /conversion/string.html From e4690cd4a465610987a5e37febb6b1ebf1e51e9d Mon Sep 17 00:00:00 2001 From: Benoit Person Date: Thu, 17 Jan 2019 21:18:17 +0000 Subject: [PATCH 0874/1122] Hello: Fix hint link in `fmt` chapter. It looks like one of the hints is pointing to an irrelevant paragraph about argument types even though the text suggests it should point to the named parameters to DRY the code a bit. --- src/hello/print/fmt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hello/print/fmt.md b/src/hello/print/fmt.md index b838fd7026..4059c97f38 100644 --- a/src/hello/print/fmt.md +++ b/src/hello/print/fmt.md @@ -79,14 +79,14 @@ RGB (0, 0, 0) 0x000000 ``` Two hints if you get stuck: - * You [may need to list each color more than once][argument_types], + * You [may need to list each color more than once][named_parameters], * You can [pad with zeros to a width of 2][fmt_width] with `:02`. ### See also [`std::fmt`][fmt] -[argument_types]: https://doc.rust-lang.org/std/fmt/#argument-types +[named_parameters]: https://doc.rust-lang.org/std/fmt/#named-parameters [deadbeef]: https://en.wikipedia.org/wiki/Deadbeef#Magic_debug_values [fmt]: https://doc.rust-lang.org/std/fmt/ [fmt_traits]: https://doc.rust-lang.org/std/fmt/#formatting-traits From 75f61dab581647321844d2ec8c6cddda5b3be5ae Mon Sep 17 00:00:00 2001 From: Casey Waldren Date: Sat, 19 Jan 2019 17:47:57 -0800 Subject: [PATCH 0875/1122] Update new_types.md to clarify conversion to base type --- src/generics/new_types.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index 47d530135d..a77282ef8a 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -40,6 +40,16 @@ fn main() { Uncomment the last print statement to observe that the type supplied must be `Years`. +To obtain the `newtype`'s value as the base type, you may use tuple syntax like so: +```rust, editable +struct Years(i64); + +fn main() { + let years = Years(42); + let years_as_primitive: i64 = years.0; +} +``` + ### See also: [`structs`][struct] From 3ce2e9ca84203f811f395dfdb2968add5be2021d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 28 Jan 2019 07:51:20 -0700 Subject: [PATCH 0876/1122] Fix compatibility with Rust 2018 --- src/generics/assoc_items/the_problem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics/assoc_items/the_problem.md b/src/generics/assoc_items/the_problem.md index e55c42fb2b..dca8f9b33f 100644 --- a/src/generics/assoc_items/the_problem.md +++ b/src/generics/assoc_items/the_problem.md @@ -18,7 +18,7 @@ struct Container(i32, i32); // A trait which checks if 2 items are stored inside of container. // Also retrieves first or last value. trait Contains { - fn contains(&self, &A, &B) -> bool; // Explicitly requires `A` and `B`. + fn contains(&self, _: &A, _: &B) -> bool; // Explicitly requires `A` and `B`. fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`. fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`. } From 145f3acfc055683fa4f6f849b0e5c0851f3b84e6 Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sun, 3 Feb 2019 16:36:49 -0800 Subject: [PATCH 0877/1122] description function in error trait is deprecated --- src/error/multiple_error_types/wrap_error.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index 15c0d662a0..be1ea35311 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -29,14 +29,6 @@ impl fmt::Display for DoubleError { } impl error::Error for DoubleError { - fn description(&self) -> &str { - match *self { - DoubleError::EmptyVec => "empty vectors not allowed", - // This already impls `Error`, so defer to its own implementation. - DoubleError::Parse(ref e) => e.description(), - } - } - fn cause(&self) -> Option<&error::Error> { match *self { DoubleError::EmptyVec => None, From 01d08e35a1cafb2fda1ed80841b563d9ede888ac Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sun, 3 Feb 2019 16:37:21 -0800 Subject: [PATCH 0878/1122] cause fn is deprecated in favor of source --- src/error/multiple_error_types/wrap_error.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index be1ea35311..f384c0c247 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -29,7 +29,7 @@ impl fmt::Display for DoubleError { } impl error::Error for DoubleError { - fn cause(&self) -> Option<&error::Error> { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { match *self { DoubleError::EmptyVec => None, // The cause is the underlying implementation error type. Is implicitly From 9143868bb61111aebe4751d2fb1ec27ddd23b4fc Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sun, 3 Feb 2019 16:40:00 -0800 Subject: [PATCH 0879/1122] remove description and replace cause with source in define_error_type.md --- src/error/multiple_error_types/define_error_type.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/error/multiple_error_types/define_error_type.md b/src/error/multiple_error_types/define_error_type.md index b7187d0d01..45e5766690 100644 --- a/src/error/multiple_error_types/define_error_type.md +++ b/src/error/multiple_error_types/define_error_type.md @@ -40,11 +40,7 @@ impl fmt::Display for DoubleError { // This is important for other errors to wrap this one. impl error::Error for DoubleError { - fn description(&self) -> &str { - "invalid first item to double" - } - - fn cause(&self) -> Option<&error::Error> { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { // Generic error, underlying cause isn't tracked. None } From 7868b8fffbe67b499f7fffcb668284968547915c Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Tue, 5 Feb 2019 10:21:05 -0600 Subject: [PATCH 0880/1122] Fix borrow so it fails in 2018 edition Fixes #1141 --- src/scope/borrow.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/scope/borrow.md b/src/scope/borrow.md index e38b717b89..2784508e50 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -30,14 +30,13 @@ fn main() { borrow_i32(&stacked_i32); { - // Take a reference to the data contained inside the box - let _ref_to_i32: &i32 = &boxed_i32; - // Error! - // Can't destroy `boxed_i32` while the inner value is borrowed. + // Can't destroy `boxed_i32` while the inner value is borrowed later in scope. eat_box_i32(boxed_i32); // FIXME ^ Comment out this line + // Take a reference to the data contained inside the box + let _ref_to_i32: &i32 = &boxed_i32; // `_ref_to_i32` goes out of scope and is no longer borrowed. } From 54479605568fc17c69f0e0d4e8030089bc8114b6 Mon Sep 17 00:00:00 2001 From: Josh Holland Date: Thu, 14 Feb 2019 22:31:02 +0000 Subject: [PATCH 0881/1122] Add "literal" to list of macro designators --- src/macros/designators.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/macros/designators.md b/src/macros/designators.md index 0ff2ed7f87..9df6540cea 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -54,6 +54,7 @@ This is a list of all the designators: * `expr` is used for expressions * `ident` is used for variable/function names * `item` +* `literal` is used for literal constants * `pat` (*pattern*) * `path` * `stmt` (*statement*) From d960310aa88cc7c6a055814c476b839afa5af4e5 Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Tue, 19 Feb 2019 23:56:10 -0600 Subject: [PATCH 0882/1122] Only trigger E505. A value is referenced. The underlying value is then destroyed. The reference is prevented from being used after the underlying value is destroyed. --- src/scope/borrow.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/scope/borrow.md b/src/scope/borrow.md index 2784508e50..51407f147c 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -29,18 +29,14 @@ fn main() { borrow_i32(&boxed_i32); borrow_i32(&stacked_i32); - { - // Error! - // Can't destroy `boxed_i32` while the inner value is borrowed later in scope. - eat_box_i32(boxed_i32); - // FIXME ^ Comment out this line - - // Take a reference to the data contained inside the box - let _ref_to_i32: &i32 = &boxed_i32; - // `_ref_to_i32` goes out of scope and is no longer borrowed. - } - - // `boxed_i32` can now give up ownership to `eat_box` and be destroyed + // Take a reference to the data contained inside the box + let _ref_to_i32: &i32 = &boxed_i32; + + // Can't destroy `boxed_i32` while the inner value is borrowed later in scope. eat_box_i32(boxed_i32); + // FIXME ^ Comment out this line + + // Attempt to borrow `_ref_to_i32` after inner value is destroyed + borrow_i32(_ref_to_i32); } ``` From 4e85201c4ed990b571146e9e2d0e4f7cf35fb08a Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 20 Feb 2019 01:15:18 -0600 Subject: [PATCH 0883/1122] Emit both E0385 and E0505. Work with 2015/2018 edition --- src/scope/borrow.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/scope/borrow.md b/src/scope/borrow.md index 51407f147c..72c70e736a 100644 --- a/src/scope/borrow.md +++ b/src/scope/borrow.md @@ -29,14 +29,21 @@ fn main() { borrow_i32(&boxed_i32); borrow_i32(&stacked_i32); - // Take a reference to the data contained inside the box - let _ref_to_i32: &i32 = &boxed_i32; + { + // Take a reference to the data contained inside the box + let _ref_to_i32: &i32 = &boxed_i32; - // Can't destroy `boxed_i32` while the inner value is borrowed later in scope. - eat_box_i32(boxed_i32); - // FIXME ^ Comment out this line + // Error! + // Can't destroy `boxed_i32` while the inner value is borrowed later in scope. + eat_box_i32(boxed_i32); + // FIXME ^ Comment out this line + + // Attempt to borrow `_ref_to_i32` after inner value is destroyed + borrow_i32(_ref_to_i32); + // `_ref_to_i32` goes out of scope and is no longer borrowed. + } - // Attempt to borrow `_ref_to_i32` after inner value is destroyed - borrow_i32(_ref_to_i32); + // `boxed_i32` can now give up ownership to `eat_box` and be destroyed + eat_box_i32(boxed_i32); } ``` From 78168dc6fceb0230e09538067b37891b644815d6 Mon Sep 17 00:00:00 2001 From: mikong <4162+mikong@users.noreply.github.com> Date: Sat, 23 Feb 2019 13:41:30 +0800 Subject: [PATCH 0884/1122] Fix grammar in sentence about integer notation Fixes #1155 --- src/primitives/literals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitives/literals.md b/src/primitives/literals.md index dee2be02f3..4927e6af82 100644 --- a/src/primitives/literals.md +++ b/src/primitives/literals.md @@ -4,7 +4,7 @@ Integers `1`, floats `1.2`, characters `'a'`, strings `"abc"`, booleans `true` and the unit type `()` can be expressed using literals. Integers can, alternatively, be expressed using hexadecimal, octal or binary -notation using either of these prefixes: `0x`, `0o` or `0b`. +notation using these prefixes respectively: `0x`, `0o` or `0b`. Underscores can be inserted in numeric literals to improve readability, e.g. `1_000` is the same as `1000`, and `0.000_001` is the same as `0.000001`. From 471dba52a8aec1aac4c48fd3c72ab432df16e56b Mon Sep 17 00:00:00 2001 From: mikong <4162+mikong@users.noreply.github.com> Date: Mon, 25 Feb 2019 12:26:39 +0800 Subject: [PATCH 0885/1122] Add link to Cargo chapter in the index page Fixes #1158 --- src/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.md b/src/index.md index f83efcdfe1..5f1572f020 100644 --- a/src/index.md +++ b/src/index.md @@ -33,6 +33,8 @@ Now let's begin! - [Crates](crates.html) - A crate is a compilation unit in Rust. Learn to create a library. +- [Cargo](cargo.html) - Go through some basic features of the official Rust package management tool. + - [Attributes](attribute.html) - An attribute is metadata applied to some module, crate or item. - [Generics](generics.html) - Learn about writing a function or data type which can work for multiple types of arguments. From 4d0848bd122d663e5296f0f777f657856ffc489f Mon Sep 17 00:00:00 2001 From: mikong <4162+mikong@users.noreply.github.com> Date: Mon, 25 Feb 2019 21:58:30 +0800 Subject: [PATCH 0886/1122] Replace lvalue and rvalue with place and value Fixes #988 --- src/expression.md | 7 ++----- src/types/inference.md | 5 +---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/expression.md b/src/expression.md index e13a075c9f..467bc10646 100644 --- a/src/expression.md +++ b/src/expression.md @@ -25,9 +25,9 @@ fn main() { } ``` -Blocks are expressions too, so they can be used as [r-values][rvalue] in +Blocks are expressions too, so they can be used as values in assignments. The last expression in the block will be assigned to the -[l-value][lvalue]. However, if the last expression of the block ends with a +place expression such as a local variable. However, if the last expression of the block ends with a semicolon, the return value will be `()`. ```rust,editable @@ -52,6 +52,3 @@ fn main() { println!("z is {:?}", z); } ``` - -[rvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue -[lvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue diff --git a/src/types/inference.md b/src/types/inference.md index be081d5f30..5d10301f42 100644 --- a/src/types/inference.md +++ b/src/types/inference.md @@ -1,8 +1,7 @@ # Inference The type inference engine is pretty smart. It does more than looking at the -type of the -[r-value][rvalue] +type of the value expression during an initialization. It also looks at how the variable is used afterwards to infer its type. Here's an advanced example of type inference: @@ -27,5 +26,3 @@ fn main() { No type annotation of variables was needed, the compiler is happy and so is the programmer! - -[rvalue]: https://en.wikipedia.org/wiki/Value_%28computer_science%29#lrvalue From fbfef92fc228edee978d0efb4421be633468f6f3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 27 Feb 2019 20:57:15 -0800 Subject: [PATCH 0887/1122] Fix some broken links. Submodules in rust-lang/rust requires links to be relative. --- src/conversion/string.md | 2 +- src/hello/print.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conversion/string.md b/src/conversion/string.md index 82101b8679..14c413a2ba 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -50,6 +50,6 @@ fn main() { [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html [Display]: https://doc.rust-lang.org/std/fmt/trait.Display.html -[print]: /hello/print.html +[print]: hello/print.html [`parse`]: https://doc.rust-lang.org/std/primitive.str.html#method.parse [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html diff --git a/src/hello/print.md b/src/hello/print.md index e91ee64bcf..2ae8c80440 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -45,7 +45,7 @@ fn main() { // used. println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" - + // Create a structure which contains an `i32`. Name it `Structure`. #[allow(dead_code)] struct Structure(i32); @@ -91,4 +91,4 @@ and [`traits`][traits] [structs]: custom_types/structs.html [traits]: trait.html [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html -[convert]: /conversion/string.html +[convert]: conversion/string.html From 21222b30e10abd6977acc3f11a5a0f63615b1b10 Mon Sep 17 00:00:00 2001 From: Carson Rajcan Date: Sun, 3 Mar 2019 10:56:37 -0600 Subject: [PATCH 0888/1122] Fix for loop description in list print example --- src/hello/print/print_display/testcase_list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index 94faa75cf0..d67d988bed 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -38,7 +38,7 @@ impl fmt::Display for List { write!(f, "[")?; - // Iterate over `vec` in `v` while enumerating the iteration + // Iterate over `v` in `vec` while enumerating the iteration // count in `count`. for (count, v) in vec.iter().enumerate() { // For every element except the first, add a comma. From 84efbba2d5a66f96e8061e935f5b424dd3ad3723 Mon Sep 17 00:00:00 2001 From: Carson Rajcan Date: Wed, 6 Mar 2019 18:23:01 -0600 Subject: [PATCH 0889/1122] Mutate array in iter_mut() example --- src/flow_control/for.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 4205b002c4..a24228e8f2 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -99,11 +99,13 @@ fn main() { let mut names = vec!["Bob", "Frank", "Ferris"]; for name in names.iter_mut() { - match name { - &mut "Ferris" => println!("There is a rustacean among us!"), - _ => println!("Hello {}", name), + *name = match name { + &mut "Ferris" => "There is a rustacean among us!", + _ => "Hello", } } + + println!("names: {:?}", names); } ``` From 075dbcaffa3c6ca8f3a85ff9e3d3f010ed53775d Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 8 Mar 2019 00:38:07 +0700 Subject: [PATCH 0890/1122] Deprecate `open_mode` in favor of OpenOptions struct Run `rustfmt` on sample code. --- src/std_misc/file/create.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md index 889d52fe58..c2dc2ada9a 100644 --- a/src/std_misc/file/create.md +++ b/src/std_misc/file/create.md @@ -5,8 +5,8 @@ already existed, the old content is destroyed. Otherwise, a new file is created. ```rust,ignore -static LOREM_IPSUM: &'static str = -"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +static LOREM_IPSUM: &str = + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse @@ -15,8 +15,8 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "; use std::error::Error; -use std::io::prelude::*; use std::fs::File; +use std::io::prelude::*; use std::path::Path; fn main() { @@ -25,18 +25,13 @@ fn main() { // Open a file in write-only mode, returns `io::Result` let mut file = match File::create(&path) { - Err(why) => panic!("couldn't create {}: {}", - display, - why.description()), + Err(why) => panic!("couldn't create {}: {}", display, why.description()), Ok(file) => file, }; // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>` match file.write_all(LOREM_IPSUM.as_bytes()) { - Err(why) => { - panic!("couldn't write to {}: {}", display, - why.description()) - }, + Err(why) => panic!("couldn't write to {}: {}", display, why.description()), Ok(_) => println!("successfully wrote to {}", display), } } @@ -60,5 +55,6 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum. (As in the previous example, you are encouraged to test this example under failure conditions.) -There is also a more generic `open_mode` method that can open files in other -modes like: read+write, append, etc. +There is [`OpenOptions`] struct that can be used to configure how a file is opened. + +[`OpenOptions`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html From 566e36e67baf4680936087b0685ce0995a333cf9 Mon Sep 17 00:00:00 2001 From: lzutao Date: Mon, 11 Mar 2019 15:42:21 +0700 Subject: [PATCH 0891/1122] Update links --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a1a9033f9e..58bba9fabb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,16 @@ # Rust By Example -[![Build Status](https://travis-ci.org/rust-lang/rust-by-example.svg?branch=master)](https://travis-ci.org/rust-lang/rust-by-example) +[![Build Status][travis-badge]][travis-repo] + +[travis-badge]: https://travis-ci.com/rust-lang/rust-by-example.svg?branch=master +[travis-repo]: https://travis-ci.com/rust-lang/rust-by-example Learn Rust with examples (Live code editor included) ## Using -If you'd like to read Rust by Example, you can visit -[https://doc.rust-lang.org/stable/rust-by-example/](https://doc.rust-lang.org/stable/rust-by-example/) to read it online. +If you'd like to read Rust by Example, you can visit https://doc.rust-lang.org/rust-by-example/ +to read it online. If you'd like to read it locally, [install Rust], and then: @@ -19,7 +22,7 @@ $ mdbook build $ mdbook serve ``` -[install Rust]: http://rust-lang.org/install.html +[install Rust]: https://www.rust-lang.org/tools/install To be able to run the examples, you must be connected to the internet; you can read all content offline, however! From dc656840efe5197158072ca6eaf8ac14d767995b Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Tue, 12 Mar 2019 14:25:36 +0900 Subject: [PATCH 0892/1122] Add score/lifetimes/trait.md --- src/SUMMARY.md | 1 + src/scope/lifetime/trait.md | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/scope/lifetime/trait.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d7169f805e..6eca451bcc 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -124,6 +124,7 @@ - [Functions](scope/lifetime/fn.md) - [Methods](scope/lifetime/methods.md) - [Structs](scope/lifetime/struct.md) + - [Traits](scope/lifetime/trait.md) - [Bounds](scope/lifetime/lifetime_bounds.md) - [Coercion](scope/lifetime/lifetime_coercion.md) - [Static](scope/lifetime/static_lifetime.md) diff --git a/src/scope/lifetime/trait.md b/src/scope/lifetime/trait.md new file mode 100644 index 0000000000..c0808ae09a --- /dev/null +++ b/src/scope/lifetime/trait.md @@ -0,0 +1,33 @@ +# Traits + +Annotation of lifetimes in trait methods basically are similar to functions. +Note that `impl` may have annotation of lifetimes too. + +```rust,editable +// A struct with annotation of lifetimes. +#[derive(Debug)] + struct Borrowed<'a> { + x: &'a i32, + } + +// Annotate lifetimes to impl. +impl<'a> Default for Borrowed<'a> { + fn default() -> Self { + Self { + x: &10, + } + } +} + +fn main() { + let b: Borrowed = Default::default(); + println!("b is {:?}", b); +} +``` + +### See also: + +[`trait`s][trait] + + +[trait]: trait.html From 24afbacccff19072fb7d052711127fee0f5997fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20Nikoli=C4=87?= Date: Sat, 13 Apr 2019 15:42:42 -0700 Subject: [PATCH 0893/1122] Fix a typo ("half" -> "halve") --- src/flow_control/if_else.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_else.md b/src/flow_control/if_else.md index 01c5d1a4b7..d761aa8388 100644 --- a/src/flow_control/if_else.md +++ b/src/flow_control/if_else.md @@ -24,7 +24,7 @@ fn main() { // This expression returns an `i32`. 10 * n } else { - println!(", and is a big number, half the number"); + println!(", and is a big number, halve the number"); // This expression must return an `i32` as well. n / 2 From e5f63b1fa2be15ec3f0c8443ea797a3972b3ee15 Mon Sep 17 00:00:00 2001 From: Alexander Clarke Date: Thu, 18 Apr 2019 10:32:55 +0100 Subject: [PATCH 0894/1122] Disable running of rust code that won't run --- src/crates/lib.md | 2 +- src/meta/doc.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crates/lib.md b/src/crates/lib.md index a46c50936f..24a51b1b2a 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -2,7 +2,7 @@ Let's create a library, and then see how to link it to another crate. -```rust,editable +```rust,ignore pub fn public_function() { println!("called rary's `public_function()`"); } diff --git a/src/meta/doc.md b/src/meta/doc.md index 4a49c2f160..f32f6a522a 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -4,7 +4,7 @@ Doc comments are very useful for big projects that require documentation. When running [Rustdoc][1], these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown][2]. -```rust,editable,ignore,mdbook-runnable +```rust,editable,ignore #![crate_name = "doc"] /// A human being is represented here From ad40cc8d73bf2b669ddbf55a4218bf7ff1bec1b5 Mon Sep 17 00:00:00 2001 From: Alexander Clarke Date: Thu, 18 Apr 2019 10:34:27 +0100 Subject: [PATCH 0895/1122] Remove unneeded ignore dead code --- src/custom_types/enum.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index c605dc988f..6756789dd4 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -5,9 +5,6 @@ different variants. Any variant which is valid as a `struct` is also valid as an `enum`. ```rust,editable -// An attribute to hide warnings for unused code. -#![allow(dead_code)] - // Create an `enum` to classify a web event. Note how both // names and type information together specify the variant: // `PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`. @@ -58,9 +55,8 @@ fn main() { ### See also: -[`attributes`][attributes], [`match`][match], [`fn`][fn], and [`String`][str] +[`match`][match], [`fn`][fn], and [`String`][str] -[attributes]: attribute.html [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [match]: flow_control/match.html [fn]: fn.html From 31048702a3caf4ca44bb9268099dbd8e9ee79ed3 Mon Sep 17 00:00:00 2001 From: Alexander Clarke Date: Thu, 18 Apr 2019 10:35:15 +0100 Subject: [PATCH 0896/1122] Improved example by using match --- .../destructuring/destructure_structures.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index d641c669b6..8e91cc31f2 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -4,26 +4,26 @@ Similarly, a `struct` can be destructured as shown: ```rust,editable fn main() { - struct Foo { x: (u32, u32), y: u32 } + struct Foo { + x: (u32, u32), + y: u32, + } - // destructure members of the struct + // Try changing the values in the struct to see what happens let foo = Foo { x: (1, 2), y: 3 }; - let Foo { x: (a, b), y } = foo; - println!("a = {}, b = {}, y = {} ", a, b, y); + match foo { + Foo { x: (1, b), y } => println!("a = 1, b = {}, y = {} ", b, y), - // you can destructure structs and rename the variables, - // the order is not important + // you can destructure structs and rename the variables, + // the order is not important + Foo { y: 2, x: i } => println!("i = {:?}, j = 2", i), - let Foo { y: i, x: j } = foo; - println!("i = {:?}, j = {:?}", i, j); - - // and you can also ignore some variables: - let Foo { y, .. } = foo; - println!("y = {}", y); - - // this will give an error: pattern does not mention field `x` - // let Foo { y } = foo; + // and you can also ignore some variables: + Foo { y, .. } => println!("y = {}", y), + // this will give an error: pattern does not mention field `x` + //Foo { y } => println!("y = {}", y); + } } ``` From aaddc14bbbc340799dcdeaeb7bcd7934af63cea5 Mon Sep 17 00:00:00 2001 From: Alexander Clarke Date: Thu, 18 Apr 2019 10:55:36 +0100 Subject: [PATCH 0897/1122] Small improvements to the example --- .../match/destructuring/destructure_structures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index 8e91cc31f2..bf35ab1897 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -13,14 +13,14 @@ fn main() { let foo = Foo { x: (1, 2), y: 3 }; match foo { - Foo { x: (1, b), y } => println!("a = 1, b = {}, y = {} ", b, y), + Foo { x: (1, b), y } => println!("First of x is 1, b = {}, y = {} ", b, y), // you can destructure structs and rename the variables, // the order is not important - Foo { y: 2, x: i } => println!("i = {:?}, j = 2", i), + Foo { y: 2, x: i } => println!("y is 2, i = {:?}", i), // and you can also ignore some variables: - Foo { y, .. } => println!("y = {}", y), + Foo { y, .. } => println!("y = {}, we don't care about x", y), // this will give an error: pattern does not mention field `x` //Foo { y } => println!("y = {}", y); } From a3fc1e5d300cace43f76b3b3aceb57d1bb740e15 Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Thu, 18 Apr 2019 17:29:33 -0700 Subject: [PATCH 0898/1122] For https://github.com/rust-lang/rust-by-example/issues/1175 --- src/flow_control/while.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/while.md b/src/flow_control/while.md index 2700b39cd6..01a8dc9ecb 100644 --- a/src/flow_control/while.md +++ b/src/flow_control/while.md @@ -1,6 +1,6 @@ # while -The `while` keyword can be used to loop until a condition is met. +The `while` keyword can be used to run a loop while a condition is true. Let's write the infamous [FizzBuzz][fizzbuzz] using a `while` loop. From d29dd5ec49caf31eb375ca520ef70352ab397d0d Mon Sep 17 00:00:00 2001 From: Bufo Alvarius <42896224+sebadoh@users.noreply.github.com> Date: Fri, 19 Apr 2019 14:23:44 -0600 Subject: [PATCH 0899/1122] 19.2 Vectors Error in Code Example https://doc.rust-lang.org/1.29.2/rust-by-example/std/vec.html Code contain an error in the following places: Line number 3: let collected_iterator: Vec = (0..10).collect(); Should be: let mut collected_iterator: Vec = (0..10).collect(); Or else Line number16 can't borrow mutably --- src/std/vec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/vec.md b/src/std/vec.md index 07408fe5b9..6ba442251d 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -10,7 +10,7 @@ be surpassed, the vector is reallocated with a larger capacity. ```rust,editable,ignore,mdbook-runnable fn main() { // Iterators can be collected into vectors - let collected_iterator: Vec = (0..10).collect(); + let mut collected_iterator: Vec = (0..10).collect(); println!("Collected (0..10) into: {:?}", collected_iterator); // The `vec!` macro can be used to initialize a vector From ac72c4f6a467b9f1a3878868d0cd93e38aeae353 Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Fri, 19 Apr 2019 21:24:22 -0700 Subject: [PATCH 0900/1122] For https://github.com/rust-lang/rust-by-example/issues/1179 --- src/scope/lifetime/lifetime_bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scope/lifetime/lifetime_bounds.md b/src/scope/lifetime/lifetime_bounds.md index e3d0a438ad..8df5f96125 100644 --- a/src/scope/lifetime/lifetime_bounds.md +++ b/src/scope/lifetime/lifetime_bounds.md @@ -8,7 +8,7 @@ but `+` is the same. Note how the following read: 2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references in `T` must outlive `'a`. -The example below shows the above syntax in action: +The example below shows the above syntax in action used after keyword `where`: ```rust,editable use std::fmt::Debug; // Trait to bound with. @@ -50,4 +50,4 @@ fn main() { [generics]: generics.html [bounds]: generics/bounds.html -[multibounds]: generics/multi_bounds.html \ No newline at end of file +[multibounds]: generics/multi_bounds.html From da3fd29a591108c804cfe32b939c8e3e82f9fb31 Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Tue, 23 Apr 2019 23:48:18 +0200 Subject: [PATCH 0901/1122] Link to Reference for macro_rules designators --- src/macros/designators.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/macros/designators.md b/src/macros/designators.md index 9df6540cea..b2230ef420 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -48,7 +48,7 @@ fn main() { } ``` -This is a list of all the designators: +These are some of the available designators: * `block` * `expr` is used for expressions @@ -61,3 +61,7 @@ This is a list of all the designators: * `tt` (*token tree*) * `ty` (*type*) * `vis` (*visibility qualifier*) + +For a complete list, see the [Rust Reference]. + +[Rust Reference]: https://doc.rust-lang.org/reference/macros-by-example.html From 144dcb367f3194fccd25af2e8b75893c71edf495 Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Wed, 24 Apr 2019 00:06:07 +0200 Subject: [PATCH 0902/1122] Improve section Meta/Docs --- src/meta/doc.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index f32f6a522a..2bb34e54ba 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -1,8 +1,16 @@ # Documentation +Use `cargo doc` to build documentation in `target/doc`. + +Use `cargo test` to run all tests (including documentation tests), and `cargo test --doc` to only run documentation tests. + +These commands will appropriately invoke `rustdoc` (and `rustc`) as required. + +### Doc comments + Doc comments are very useful for big projects that require documentation. When -running [Rustdoc][1], these are the comments that get compiled into -documentation. They are denoted by a `///`, and support [Markdown][2]. +running Rustdoc, these are the comments that get compiled into +documentation. They are denoted by a `///`, and support [Markdown]. ```rust,editable,ignore #![crate_name = "doc"] @@ -57,8 +65,19 @@ $ rustc doc.rs --crate-type lib $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` -(When you run `cargo test` on a library crate, Cargo will automatically -generate and run the correct rustc and rustdoc commands.) +### See also: + +* [The Rust Book: Making Useful Documentation Comments][book] +* [The Rustdoc Book][rustdoc-book] +* [The Reference: Doc comments][ref-comments] +* [RFC 1574: API Documentation Conventions][api-conv] +* [RFC 1946: Relative links to other items from doc comments (intra-rustdoc links)][intra-links] +* [Is there any documentation style guide for comments? (reddit)][reddit] -[1]: https://doc.rust-lang.org/book/documentation.html -[2]: https://en.wikipedia.org/wiki/Markdown +[Markdown]: https://en.wikipedia.org/wiki/Markdown +[book]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments +[ref-comments]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments +[rustdoc-book]: https://doc.rust-lang.org/rustdoc/index.html +[api-conv]: https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text +[intra-links]: https://rust-lang.github.io/rfcs/1946-intra-rustdoc-links.html +[reddit]: https://www.reddit.com/r/rust/comments/ahb50s/is_there_any_documentation_style_guide_for/ From 0ea18a78cf90f64004c54fc3589b57844d78561f Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Tue, 23 Apr 2019 21:30:39 -0700 Subject: [PATCH 0903/1122] For https://github.com/rust-lang/rust-by-example/issues/1184 --- src/flow_control/if_let.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 450354af42..9b93a273a3 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -94,6 +94,26 @@ fn main() { } ``` +Another benefit: `if let` allows to match enum non-parameterized variants, even if the enum doesn't `#[derive(PartialEq)]`, neither we implement `PartialEq` for it. In such case, classic `if Foo::Bar==a` fails, because instances of such enum are not comparable for equality. However, `if let` works. + +Would you like a challenge? Fix the following example to use `if let`: + +```rust,editable +// This enum purposely doesn't #[derive(PartialEq)], +// neither we implement PartialEq for it. That's why comparing Foo::Bar==a fails below. +enum Foo {Bar} + +fn main() { + let a = Foo::Bar; + + // Variable a matches Foo::Bar + if Foo::Bar == a { + // ^-- this causes a compile-time error. Use `if let` instead. + println!("a is foobar"); + } +} +``` + ### See also: [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] From c75b3d49116c93b0d0fa6139883d5adceff738f2 Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Wed, 24 Apr 2019 11:07:11 -0700 Subject: [PATCH 0904/1122] Added "ignore" for an example that is supposed to fail compilation --- src/flow_control/if_let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 9b93a273a3..ffbf0da989 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -98,7 +98,7 @@ Another benefit: `if let` allows to match enum non-parameterized variants, even Would you like a challenge? Fix the following example to use `if let`: -```rust,editable +```rust,editable,ignore // This enum purposely doesn't #[derive(PartialEq)], // neither we implement PartialEq for it. That's why comparing Foo::Bar==a fails below. enum Foo {Bar} From bbf801d8e84ce7a4a8347ba450bf61b207a07077 Mon Sep 17 00:00:00 2001 From: Andrew Gauger Date: Fri, 26 Apr 2019 10:02:23 -0700 Subject: [PATCH 0905/1122] example to read a file line by line --- src/SUMMARY.md | 1 + src/std_misc/file/read_lines.md | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/std_misc/file/read_lines.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6eca451bcc..2056c4381e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -184,6 +184,7 @@ - [File I/O](std_misc/file.md) - [`open`](std_misc/file/open.md) - [`create`](std_misc/file/create.md) + - [`read lines`](std_misc/file/read_lines.md) - [Child processes](std_misc/process.md) - [Pipes](std_misc/process/pipe.md) - [Wait](std_misc/process/wait.md) diff --git a/src/std_misc/file/read_lines.md b/src/std_misc/file/read_lines.md new file mode 100644 index 0000000000..95b39f8f7c --- /dev/null +++ b/src/std_misc/file/read_lines.md @@ -0,0 +1,43 @@ +# Read Lines + +The method `lines()` returns an iterator over the lines +of a file. + +`File::open` expects a generic, `AsRef`. That's what +`read_lines()` expects as input. + +```rust,no_run +use std::fs::File; +use std::io::{self, BufRead}; +use std::path::Path; + +fn main() { + // File hosts must exist in current path before this produces output + if let Ok(lines) = read_lines("./hosts") { + // Consumes the iterator, returns an (Optional) String + for line in lines { + if let Ok(ip) = line { + println!("{}", ip); + } + } + } +} + +// The output is wrapped in a Result to allow matching on errors +// Returns an Iterator to the Reader of the lines of the file. +fn read_lines

(filename: P) -> io::Result>> +where P: AsRef, { + let file = File::open(filename)?; + Ok(io::BufReader::new(file).lines()) +} +``` + +Running this program simply returns the lines individually. +```bash +$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts +$ rustc read_lines.rs && ./read_lines +127.0.0.1 +192.168.0.1 +``` + +This process is more efficient that creating a `String` in memory for larger files. \ No newline at end of file From 6e44483a5772e1a9c51586d61d3b917afd52b1d7 Mon Sep 17 00:00:00 2001 From: Andrew Gauger Date: Fri, 26 Apr 2019 10:04:28 -0700 Subject: [PATCH 0906/1122] spelling --- src/std_misc/file/read_lines.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/std_misc/file/read_lines.md b/src/std_misc/file/read_lines.md index 95b39f8f7c..2a2f1855dc 100644 --- a/src/std_misc/file/read_lines.md +++ b/src/std_misc/file/read_lines.md @@ -32,7 +32,7 @@ where P: AsRef, { } ``` -Running this program simply returns the lines individually. +Running this program simply prints the lines individually. ```bash $ echo -e "127.0.0.1\n192.168.0.1\n" > hosts $ rustc read_lines.rs && ./read_lines @@ -40,4 +40,5 @@ $ rustc read_lines.rs && ./read_lines 192.168.0.1 ``` -This process is more efficient that creating a `String` in memory for larger files. \ No newline at end of file +This process is more efficient than creating a `String` in memory +especially working with larger files. \ No newline at end of file From e477dbb01bd9f21573d3d4cd6a78bfc72eb993dc Mon Sep 17 00:00:00 2001 From: Konstankino LLC Date: Sat, 27 Apr 2019 14:05:50 -0700 Subject: [PATCH 0907/1122] Fix typo in dsl.md --- src/macros/dsl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros/dsl.md b/src/macros/dsl.md index de28910cd0..fb0c23550d 100644 --- a/src/macros/dsl.md +++ b/src/macros/dsl.md @@ -6,7 +6,7 @@ like a small language. This allows you to define concise or intuitive syntax for some special functionality (within bounds). Suppose that I want to define a little calculator API. I would like to supply -an expression an have the output printed to console. +an expression and have the output printed to console. ```rust,editable macro_rules! calculate { From 023dfdb230be7652e290f9aa13b3bc15ebfbc2c4 Mon Sep 17 00:00:00 2001 From: utsavoza Date: Sun, 19 May 2019 00:19:00 +0530 Subject: [PATCH 0908/1122] Fix typo in a mod visibility example --- src/mod/visibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/visibility.md b/src/mod/visibility.md index 46c0b6abd1..2c3ca8b89a 100644 --- a/src/mod/visibility.md +++ b/src/mod/visibility.md @@ -56,7 +56,7 @@ mod my_mod { } pub fn call_public_function_in_my_mod() { - print!("called `my_mod::call_public_funcion_in_my_mod()`, that\n> "); + print!("called `my_mod::call_public_function_in_my_mod()`, that\n> "); nested::public_function_in_my_mod(); print!("> "); nested::public_function_in_super_mod(); From 765b4c47ab39ee42eda43d92a2f5d82e964aa733 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Sun, 19 May 2019 16:28:20 -0700 Subject: [PATCH 0909/1122] Copy edits to chapter 1 --- src/hello.md | 6 ++-- src/hello/comment.md | 34 +++++++++---------- src/hello/print.md | 16 ++++----- src/hello/print/fmt.md | 4 +-- src/hello/print/print_debug.md | 2 +- src/hello/print/print_display.md | 14 ++++---- .../print/print_display/testcase_list.md | 4 +-- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/hello.md b/src/hello.md index a11e309a06..22a4de7f7e 100644 --- a/src/hello.md +++ b/src/hello.md @@ -3,16 +3,16 @@ This is the source code of the traditional Hello World program. ```rust,editable -// This is a comment, and will be ignored by the compiler +// This is a comment, and is ignored by the compiler // You can test this code by clicking the "Run" button over there -> -// or if prefer to use your keyboard, you can use the "Ctrl + Enter" shortcut +// or if you prefer to use your keyboard, you can use the "Ctrl + Enter" shortcut // This code is editable, feel free to hack it! // You can always return to the original code by clicking the "Reset" button -> // This is the main function fn main() { - // The statements here will be executed when the compiled binary is called + // Statements here are executed when the compiled binary is called // Print text to the console println!("Hello World!"); diff --git a/src/hello/comment.md b/src/hello/comment.md index 951b7df858..dc4a9dca09 100644 --- a/src/hello/comment.md +++ b/src/hello/comment.md @@ -1,43 +1,43 @@ # Comments -Any program requires comments and indeed Rust supports +Any program requires comments, and Rust supports a few different varieties: * *Regular comments* which are ignored by the compiler: - - `// Line comments which go to the end of the line.` - - `/* Block comments which go to the closing delimiter. */` + * `// Line comments which go to the end of the line.` + * `/* Block comments which go to the closing delimiter. */` * *Doc comments* which are parsed into HTML library -[documentation][docs]: - - `/// Generate library docs for the following item.` - - `//! Generate library docs for the enclosing item.` + [documentation][docs]: + * `/// Generate library docs for the following item.` + * `//! Generate library docs for the enclosing item.` ```rust,editable fn main() { // This is an example of a line comment - // Notice how there are two slashes at the beginning of the line - // And that nothing written inside these will be read by the compiler + // There are two slashes at the beginning of the line + // And nothing written inside these will be read by the compiler // println!("Hello, world!"); // Run it. See? Now try deleting the two slashes, and run it again. /* - * This is another type of comment, the block comment. In general, - * the line comment is the recommended comment style however the - * block comment is extremely useful for temporarily disabling - * a large chunk of code. /* Block comments can be /* nested, */ */ - * so it takes only a few keystrokes to comment out all the lines + * This is another type of comment, a block comment. In general, + * line comments are the recommended comment style. But + * block comments are extremely useful for temporarily disabling + * chunks of code. /* Block comments can be /* nested, */ */ + * so it takes only a few keystrokes to comment out everything * in this main() function. /*/*/* Try it yourself! */*/*/ */ /* - Note, the previous column of `*` was entirely for style. There's + Note: The previous column of `*` was entirely for style. There's no actual need for it. */ - // Observe how block comments allow easy expression manipulation - // which line comments do not. Deleting the comment delimiters - // will change the result: + // You can manipulate expressions more easily with block comments + // than with line comments. Try deleting the comment delimiters + // to change the result: let x = 5 + /* 90 + */ 5; println!("Is `x` 10 or 100? x = {}", x); } diff --git a/src/hello/print.md b/src/hello/print.md index 2ae8c80440..c335493bd3 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -9,8 +9,8 @@ some of which include: * `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr). * `eprintln!`: same as `eprint!`but a newline is appended. -All parse text in the same fashion. A plus is that the formatting correctness will -be checked at compile time. +All parse text in the same fashion. As a plus, Rust checks formatting +correctness at compile time. ```rust,editable,ignore,mdbook-runnable fn main() { @@ -18,8 +18,8 @@ fn main() { // arguments. These will be stringified. println!("{} days", 31); - // Without a suffix, 31 becomes an i32. You can change what type 31 is, - // with a suffix. + // Without a suffix, 31 becomes an i32. You can change what type 31 is + // by providing a suffix. // There are various optional patterns this works with. Positional // arguments can be used. @@ -41,12 +41,12 @@ fn main() { // You can pad numbers with extra zeroes. This will output "000001". println!("{number:>0width$}", number=1, width=6); - // It will even check to make sure the correct number of arguments are + // Rust even checks to make sure the correct number of arguments are // used. println!("My name is {0}, {1} {0}", "Bond"); // FIXME ^ Add the missing argument: "James" - // Create a structure which contains an `i32`. Name it `Structure`. + // Create a structure named `Structure` which contains an `i32`. #[allow(dead_code)] struct Structure(i32); @@ -64,7 +64,7 @@ of text. The base form of two important ones are listed below: * `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user friendly fashion. -Here, `fmt::Display` was used because the std library provides implementations +Here, we used `fmt::Display `because the std library provides implementations for these types. To print text for custom types, more steps are required. Implementing the `fmt::Display` trait automagically implements the @@ -76,7 +76,7 @@ Implementing the `fmt::Display` trait automagically implements the error. * Add a `println!` macro that prints: `Pi is roughly 3.142` by controlling the number of decimal places shown. For the purposes of this exercise, - use `let pi = 3.141592` as an estimate for Pi. (Hint: you may need to + use `let pi = 3.141592` as an estimate for pi. (Hint: you may need to check the [`std::fmt`][fmt] documentation for setting the number of decimals to display) diff --git a/src/hello/print/fmt.md b/src/hello/print/fmt.md index 4059c97f38..5cdcda89f0 100644 --- a/src/hello/print/fmt.md +++ b/src/hello/print/fmt.md @@ -26,7 +26,7 @@ struct City { } impl Display for City { - // `f` is a buffer, this method must write the formatted string into it + // `f` is a buffer, and this method must write the formatted string into it fn fmt(&self, f: &mut Formatter) -> fmt::Result { let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' }; @@ -59,7 +59,7 @@ fn main() { Color { red: 0, green: 0, blue: 0 }, ].iter() { // Switch this to use {} once you've added an implementation - // for fmt::Display + // for fmt::Display. println!("{:?}", *color); } } diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index 4e68b7fadc..0173e35794 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -11,7 +11,7 @@ not true for `fmt::Display` which must be manually implemented. ```rust // This structure cannot be printed either with `fmt::Display` or -// with `fmt::Debug` +// with `fmt::Debug`. struct UnPrintable(i32); // The `derive` attribute automatically creates the implementation diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index dc86ff2edf..28f838dd39 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -9,11 +9,11 @@ looks like this: // Import (via `use`) the `fmt` module to make it available. use std::fmt; -// Define a structure which `fmt::Display` will be implemented for. This is simply -// a tuple struct containing an `i32` bound to the name `Structure`. +// Define a structure for which `fmt::Display` will be implemented. This is +// a tuple struct named `Structure` that contains an `i32`. struct Structure(i32); -// In order to use the `{}` marker, the trait `fmt::Display` must be implemented +// To use the `{}` marker, the trait `fmt::Display` must be implemented // manually for the type. impl fmt::Display for Structure { // This trait requires `fmt` with this exact signature. @@ -30,7 +30,7 @@ impl fmt::Display for Structure { `fmt::Display` may be cleaner than `fmt::Debug` but this presents a problem for the `std` library. How should ambiguous types be displayed? For example, if the `std` library implemented a single style for all -`Vec`, what style should it be? Either of these two? +`Vec`, what style should it be? Would it be either of these two? * `Vec`: `/:/etc:/home/username:/bin` (split on `:`) * `Vec`: `1,2,3` (split on `,`) @@ -66,7 +66,7 @@ struct Point2D { y: f64, } -// Similarly, implement for Point2D +// Similarly, implement `Display` for `Point2D` impl fmt::Display for Point2D { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Customize so only `x` and `y` are denoted. @@ -94,7 +94,7 @@ fn main() { println!("Display: {}", point); println!("Debug: {:?}", point); - // Error. Both `Debug` and `Display` were implemented but `{:b}` + // Error. Both `Debug` and `Display` were implemented, but `{:b}` // requires `fmt::Binary` to be implemented. This will not work. // println!("What does Point2D look like in binary: {:b}?", point); } @@ -107,7 +107,7 @@ each requires its own implementation. This is detailed further in ### Activity -After checking the output of the above example, use the `Point2D` struct as +After checking the output of the above example, use the `Point2D` struct as a guide to add a Complex struct to the example. When printed in the same way, the output should be: diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index d67d988bed..87301ba58b 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -32,7 +32,7 @@ struct List(Vec); impl fmt::Display for List { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Extract the value using tuple indexing + // Extract the value using tuple indexing, // and create a reference to `vec`. let vec = &self.0; @@ -47,7 +47,7 @@ impl fmt::Display for List { write!(f, "{}", v)?; } - // Close the opened bracket and return a fmt::Result value + // Close the opened bracket and return a fmt::Result value. write!(f, "]") } } From c6220104c6d4c53cac19a50ad07870875b1b8b9a Mon Sep 17 00:00:00 2001 From: Russell Davis <551404+russelldavis@users.noreply.github.com> Date: Mon, 20 May 2019 17:51:59 -0700 Subject: [PATCH 0910/1122] Reword "Flow Control" to "Flow of Control" It's a bit of a nit, but flow control generally refers to something different. The way it's being used here, it's usually worded as flow *of* control or control flow. References: https://en.wikipedia.org/wiki/Flow_control https://en.wikipedia.org/wiki/Control_flow --- src/SUMMARY.md | 2 +- src/flow_control.md | 2 +- src/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2056c4381e..7d91af4307 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -40,7 +40,7 @@ - [Expressions](expression.md) -- [Flow Control](flow_control.md) +- [Flow of Control](flow_control.md) - [if/else](flow_control/if_else.md) - [loop](flow_control/loop.md) - [Nesting and labels](flow_control/loop/nested.md) diff --git a/src/flow_control.md b/src/flow_control.md index 4cd6d0d8e7..c8a2f9ed87 100644 --- a/src/flow_control.md +++ b/src/flow_control.md @@ -1,4 +1,4 @@ -# Flow Control +# Flow of Control An essential part of any programming languages are ways to modify control flow: `if`/`else`, `for`, and others. Let's talk about them in Rust. diff --git a/src/index.md b/src/index.md index 5f1572f020..ad7024a516 100644 --- a/src/index.md +++ b/src/index.md @@ -25,7 +25,7 @@ Now let's begin! - [Expressions](expression.html) -- [Flow Control](flow_control.html) - `if`/`else`, `for`, and others. +- [Flow of Control](flow_control.html) - `if`/`else`, `for`, and others. - [Functions](fn.html) - Learn about Methods, Closures and High Order Functions. From ce6c8344d62719bc93e45ae8ad404e75f606467e Mon Sep 17 00:00:00 2001 From: Russell Davis <551404+russelldavis@users.noreply.github.com> Date: Tue, 21 May 2019 08:38:37 -0700 Subject: [PATCH 0911/1122] Fix usage of the word "elision" This seems to have been written with the notion that "elide" means "infer" or "emit" rather than the actual meaning of "omit". --- src/scope/lifetime/elision.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scope/lifetime/elision.md b/src/scope/lifetime/elision.md index 9a7204b25d..d1897e7e62 100644 --- a/src/scope/lifetime/elision.md +++ b/src/scope/lifetime/elision.md @@ -1,16 +1,16 @@ # Elision Some lifetime patterns are overwhelmingly common and so the borrow checker -will implicitly add them to save typing and to improve readability. -This process of implicit addition is called elision. Elision exists in Rust -solely because these patterns are common. +will allow you to omit them to save typing and to improve readability. +This is known as elision. Elision exists in Rust solely because these patterns +are common. The following code shows a few examples of elision. For a more comprehensive description of elision, see [lifetime elision][elision] in the book. ```rust,editable // `elided_input` and `annotated_input` essentially have identical signatures -// because the lifetime of `elided_input` is elided by the compiler: +// because the lifetime of `elided_input` is inferred by the compiler: fn elided_input(x: &i32) { println!("`elided_input`: {}", x); } From 871643a551185c5ae328cff0285169bf8de384d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Thu, 30 May 2019 00:11:49 +0200 Subject: [PATCH 0912/1122] Fixed wording in the `Seconds` struct description. --- src/trait/derive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/derive.md b/src/trait/derive.md index ff37bffc67..4ef87cdb38 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -30,7 +30,7 @@ impl Inches { } } -// `Seconds`, a tuple struct no additional attributes +// `Seconds`, a tuple struct with no additional attributes struct Seconds(i32); fn main() { From cad22d61a2dc5d99be01a0a993f499b8185d8679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Thu, 30 May 2019 00:43:21 +0200 Subject: [PATCH 0913/1122] Added parameters names to trait method declaration In accordance with RFC #1685, parameters in trait method declarations are no longer allowed to be anonymous. https://github.com/rust-lang/rfcs/pull/1685 --- src/generics/assoc_items/types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics/assoc_items/types.md b/src/generics/assoc_items/types.md index 25196f2e0e..0358fcebca 100644 --- a/src/generics/assoc_items/types.md +++ b/src/generics/assoc_items/types.md @@ -41,7 +41,7 @@ trait Contains { type A; type B; - fn contains(&self, &Self::A, &Self::B) -> bool; + fn contains(&self, _: &Self::A, _: &Self::B) -> bool; fn first(&self) -> i32; fn last(&self) -> i32; } From 809776f1167f97163dfcf203dc4fc9dae59496ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Sun, 2 Jun 2019 13:47:22 +0200 Subject: [PATCH 0914/1122] Upgrade links to match mdbook 0.2 --- src/attribute.md | 4 +- src/attribute/cfg.md | 2 +- src/compatibility.md | 2 +- src/conversion.md | 2 +- src/conversion/string.md | 2 +- src/crates/lib.md | 2 +- src/custom_types/constants.md | 4 +- src/custom_types/enum.md | 6 +-- src/custom_types/enum/c_like.md | 2 +- src/custom_types/enum/enum_use.md | 4 +- src/custom_types/enum/testcase_linked_list.md | 4 +- src/custom_types/structs.md | 4 +- .../multiple_error_types/option_result.md | 2 +- src/error/multiple_error_types/wrap_error.md | 2 +- src/error/option_unwrap/and_then.md | 2 +- src/error/option_unwrap/map.md | 2 +- src/error/result.md | 2 +- src/error/result/enter_question_mark.md | 2 +- src/error/result/result_alias.md | 2 +- src/flow_control/for.md | 2 +- src/flow_control/if_let.md | 4 +- src/flow_control/match/binding.md | 2 +- src/flow_control/match/destructuring.md | 8 ++-- .../match/destructuring/destructure_enum.md | 4 +- .../destructuring/destructure_structures.md | 2 +- .../match/destructuring/destructure_tuple.md | 2 +- src/flow_control/match/guard.md | 2 +- src/flow_control/while_let.md | 4 +- src/fn/closures/anonymity.md | 2 +- src/fn/closures/capture.md | 2 +- src/fn/closures/output_parameters.md | 4 +- src/generics.md | 2 +- src/generics/assoc_items/the_problem.md | 4 +- src/generics/bounds.md | 10 ++-- src/generics/bounds/testcase_empty.md | 2 +- src/generics/gen_fn.md | 4 +- src/generics/gen_trait.md | 4 +- src/generics/impl.md | 6 +-- src/generics/multi_bounds.md | 4 +- src/generics/new_types.md | 2 +- src/generics/phantom.md | 6 +-- src/generics/phantom/testcase_units.md | 16 +++---- src/generics/where.md | 4 +- src/hello.md | 2 +- src/hello/comment.md | 2 +- src/hello/print.md | 10 ++-- src/hello/print/print_debug.md | 4 +- src/hello/print/print_display.md | 10 ++-- .../print/print_display/testcase_list.md | 12 ++--- src/index.md | 48 +++++++++---------- src/macros/syntax.md | 6 +-- src/mod/split.md | 2 +- src/mod/struct_visibility.md | 4 +- src/primitives.md | 6 +-- src/primitives/tuples.md | 2 +- src/scope/borrow/mut.md | 2 +- src/scope/lifetime/explicit.md | 8 ++-- src/scope/lifetime/fn.md | 4 +- src/scope/lifetime/lifetime_bounds.md | 6 +-- src/scope/lifetime/methods.md | 2 +- src/scope/lifetime/static_lifetime.md | 2 +- src/scope/lifetime/struct.md | 2 +- src/scope/lifetime/trait.md | 2 +- src/scope/move.md | 2 +- src/scope/raii.md | 2 +- src/std.md | 2 +- src/std_misc.md | 2 +- src/std_misc/fs.md | 2 +- src/std_misc/threads/testcase_mapreduce.md | 12 ++--- src/testing.md | 8 ++-- src/testing/integration_testing.md | 4 +- src/testing/unit_testing.md | 8 ++-- src/trait/derive.md | 2 +- src/types.md | 8 ++-- src/types/alias.md | 2 +- src/types/literals.md | 6 +-- src/unsafe.md | 2 +- 77 files changed, 176 insertions(+), 176 deletions(-) diff --git a/src/attribute.md b/src/attribute.md index 1b81c09976..13b0a60b46 100644 --- a/src/attribute.md +++ b/src/attribute.md @@ -33,6 +33,6 @@ Attributes can have multiple values and can be separated over multiple lines, to value4, value5)] ``` -[cfg]: attribute/cfg.html -[crate]: attribute/crate.html +[cfg]: attribute/cfg.md +[crate]: attribute/crate.md [lint]: https://en.wikipedia.org/wiki/Lint_%28software%29 diff --git a/src/attribute/cfg.md b/src/attribute/cfg.md index e7b56559f2..1b20e12f4d 100644 --- a/src/attribute/cfg.md +++ b/src/attribute/cfg.md @@ -37,5 +37,5 @@ fn main() { [the reference][ref], [`cfg!`][cfg], and [macros][macros]. [cfg]: https://doc.rust-lang.org/std/macro.cfg!.html -[macros]: macros.html +[macros]: ../macros.md [ref]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation diff --git a/src/compatibility.md b/src/compatibility.md index c756e25d71..00424ceb22 100644 --- a/src/compatibility.md +++ b/src/compatibility.md @@ -4,4 +4,4 @@ The Rust language is fastly evolving, and because of this certain compatibility issues can arise, despite efforts to ensure forwards-compatibility wherever possible. -* [Raw identifiers](compatibility/raw_identifiers.html) +* [Raw identifiers](compatibility/raw_identifiers.md) diff --git a/src/conversion.md b/src/conversion.md index f7f950ce32..78d9e2d31e 100644 --- a/src/conversion.md +++ b/src/conversion.md @@ -5,6 +5,6 @@ conversions will use the [`From`] and [`Into`] traits. However there are more specific ones for the more common cases, in particular when converting to and from `String`s. -[traits]: trait.html +[traits]: trait.md [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html diff --git a/src/conversion/string.md b/src/conversion/string.md index 14c413a2ba..2bec02f6df 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -50,6 +50,6 @@ fn main() { [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html [Display]: https://doc.rust-lang.org/std/fmt/trait.Display.html -[print]: hello/print.html +[print]: ../hello/print.md [`parse`]: https://doc.rust-lang.org/std/primitive.str.html#method.parse [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html diff --git a/src/crates/lib.md b/src/crates/lib.md index 24a51b1b2a..f20fe5990e 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -28,4 +28,4 @@ Libraries get prefixed with "lib", and by default they get named after their crate file, but this default name can be overridden using the [`crate_name` attribute][crate-name]. -[crate-name]: attribute/crate.html \ No newline at end of file +[crate-name]: ../attribute/crate.md \ No newline at end of file diff --git a/src/custom_types/constants.md b/src/custom_types/constants.md index 5fb868b9b5..8878ba834e 100644 --- a/src/custom_types/constants.md +++ b/src/custom_types/constants.md @@ -38,5 +38,5 @@ fn main() { https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md), [`'static` lifetime][static] -[static]: scope/lifetime/static_lifetime.html -[unsafe]: unsafe.html +[static]: ../scope/lifetime/static_lifetime.md +[unsafe]: ../unsafe.md diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index 6756789dd4..51683fb8e3 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -58,6 +58,6 @@ fn main() { [`match`][match], [`fn`][fn], and [`String`][str] [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[match]: flow_control/match.html -[fn]: fn.html -[str]: std/str.html +[match]: ../flow_control/match.md +[fn]: ../fn.md +[str]: ../std/str.md diff --git a/src/custom_types/enum/c_like.md b/src/custom_types/enum/c_like.md index 9dbc37c270..65f832bef8 100644 --- a/src/custom_types/enum/c_like.md +++ b/src/custom_types/enum/c_like.md @@ -34,4 +34,4 @@ fn main() { [casting][cast] -[cast]: types/cast.html +[cast]: ../../types/cast.md diff --git a/src/custom_types/enum/enum_use.md b/src/custom_types/enum/enum_use.md index a6ac21a9b2..cf75c67ba4 100644 --- a/src/custom_types/enum/enum_use.md +++ b/src/custom_types/enum/enum_use.md @@ -46,5 +46,5 @@ fn main() { [`match`][match] and [`use`][use] -[use]: mod/use.html -[match]: flow_control/match.html +[use]: ../../mod/use.md +[match]: ../../flow_control/match.md diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index 61109d1596..84855d1c54 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -75,5 +75,5 @@ fn main() { [`Box`][box] and [methods][methods] -[box]: std/box.html -[methods]: fn/methods.html +[box]: ../../std/box.md +[methods]: ../../fn/methods.md diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index f51d67a74d..0b620bf38a 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -89,6 +89,6 @@ fn main() { [`attributes`][attributes] and [destructuring][destructuring] -[attributes]: attribute.html +[attributes]: ../attribute.md [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) -[destructuring]: flow_control/match/destructuring.html +[destructuring]: ../flow_control/match/destructuring.md diff --git a/src/error/multiple_error_types/option_result.md b/src/error/multiple_error_types/option_result.md index 331b458189..793673f8df 100644 --- a/src/error/multiple_error_types/option_result.md +++ b/src/error/multiple_error_types/option_result.md @@ -55,4 +55,4 @@ fn main() { } ``` -[enter_question_mark]: error/result/enter_question_mark.html +[enter_question_mark]: ../result/enter_question_mark.md diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index f384c0c247..e8acd25197 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -83,4 +83,4 @@ for you. [`From::from`][from] and [`Enums`][enums] [from]: https://doc.rust-lang.org/std/convert/trait.From.html -[enums]: custom_types/enum.html +[enums]: ../../custom_types/enum.md diff --git a/src/error/option_unwrap/and_then.md b/src/error/option_unwrap/and_then.md index 99d8133ac6..c065f2043e 100644 --- a/src/error/option_unwrap/and_then.md +++ b/src/error/option_unwrap/and_then.md @@ -71,6 +71,6 @@ fn main() { [closures][closures], [`Option`][option], and [`Option::and_then()`][and_then] -[closures]: fn/closures.html +[closures]: ../../fn/closures.md [option]: https://doc.rust-lang.org/std/option/enum.Option.html [and_then]: https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/src/error/option_unwrap/map.md b/src/error/option_unwrap/map.md index 89b06cca90..c458e7d955 100644 --- a/src/error/option_unwrap/map.md +++ b/src/error/option_unwrap/map.md @@ -81,6 +81,6 @@ fn main() { [closures][closures], [`Option`][option], [`Option::map()`][map] [combinators]: https://doc.rust-lang.org/book/glossary.html#combinators -[closures]: fn/closures.html +[closures]: ../../fn/closures.md [option]: https://doc.rust-lang.org/std/option/enum.Option.html [map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map diff --git a/src/error/result.md b/src/error/result.md index 1dede872e8..3202b314ea 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -80,4 +80,4 @@ fn main() -> Result<(), ParseIntError> { [result]: https://doc.rust-lang.org/std/result/enum.Result.html [parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse [`Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html -[the following section]: error/result/early_returns.html +[the following section]: result/early_returns.md diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index aa4627c2c3..ff4be176f0 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -69,4 +69,4 @@ fn main() { [^†]: See [re-enter ?][re_enter_?] for more details. -[re_enter_?]: error/multiple_error_types/reenter_question_mark.html +[re_enter_?]: ../multiple_error_types/reenter_question_mark.md diff --git a/src/error/result/result_alias.md b/src/error/result/result_alias.md index c0466357b1..c4073980fc 100644 --- a/src/error/result/result_alias.md +++ b/src/error/result/result_alias.md @@ -42,5 +42,5 @@ fn main() { [`io::Result`][io_result] -[typealias]: types/alias.html +[typealias]: ../../types/alias.md [io_result]: https://doc.rust-lang.org/std/io/type.Result.html diff --git a/src/flow_control/for.md b/src/flow_control/for.md index a24228e8f2..a8a4762a2d 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -117,4 +117,4 @@ implies differing actions that are able to be performed. [Iterator][iter] -[iter]: trait/iter.html +[iter]: ../trait/iter.md diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index ffbf0da989..bcdebcedbd 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -118,6 +118,6 @@ fn main() { [`enum`][enum], [`Option`][option], and the [RFC][if_let_rfc] -[enum]: custom_types/enum.html +[enum]: ../custom_types/enum.md [if_let_rfc]: https://github.com/rust-lang/rfcs/pull/160 -[option]: std/option.html +[option]: ../std/option.md diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index 9a22503207..385035dc15 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -29,4 +29,4 @@ fn main() { ### See also: [functions] -[functions]: fn.html +[functions]: ../../fn.md diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index ce59b15407..9f9a73e025 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -8,7 +8,7 @@ A `match` block can destructure items in a variety of ways. * [Destructuring Tuples][tuple] -[enum]: flow_control/match/destructuring/destructure_enum.html -[refs]: flow_control/match/destructuring/destructure_pointers.html -[struct]: flow_control/match/destructuring/destructure_structures.html -[tuple]: flow_control/match/destructuring/destructure_tuple.html +[enum]: destructuring/destructure_enum.md +[refs]: destructuring/destructure_pointers.md +[struct]: destructuring/destructure_structures.md +[tuple]: destructuring/destructure_tuple.md diff --git a/src/flow_control/match/destructuring/destructure_enum.md b/src/flow_control/match/destructuring/destructure_enum.md index a5022330ba..60d8969459 100644 --- a/src/flow_control/match/destructuring/destructure_enum.md +++ b/src/flow_control/match/destructuring/destructure_enum.md @@ -49,6 +49,6 @@ fn main() { [`#[allow(...)]`][allow], [color models][color_models] and [`enum`][enum] -[allow]: attribute/unused.html +[allow]: ../../../attribute/unused.md [color_models]: https://en.wikipedia.org/wiki/Color_model -[enum]: custom_types/enum.html +[enum]: ../../../custom_types/enum.md diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index bf35ab1897..35ce28db87 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -29,4 +29,4 @@ fn main() { ### See also: -[Structs](custom_types/structs.html), [The ref pattern](scope/borrow/ref.html) +[Structs](../../../custom_types/structs.md), [The ref pattern](../../../scope/borrow/ref.md) diff --git a/src/flow_control/match/destructuring/destructure_tuple.md b/src/flow_control/match/destructuring/destructure_tuple.md index c7e1024aca..9d6260e433 100644 --- a/src/flow_control/match/destructuring/destructure_tuple.md +++ b/src/flow_control/match/destructuring/destructure_tuple.md @@ -21,4 +21,4 @@ fn main() { ### See also: -[Tuples](primitives/tuples.html) +[Tuples](../../../primitives/tuples.md) diff --git a/src/flow_control/match/guard.md b/src/flow_control/match/guard.md index e52c198e8f..336b7f1233 100644 --- a/src/flow_control/match/guard.md +++ b/src/flow_control/match/guard.md @@ -20,4 +20,4 @@ fn main() { ### See also: -[Tuples](primitives/tuples.html) +[Tuples](../../primitives/tuples.md) diff --git a/src/flow_control/while_let.md b/src/flow_control/while_let.md index 5938de4ee4..897375a8e2 100644 --- a/src/flow_control/while_let.md +++ b/src/flow_control/while_let.md @@ -57,6 +57,6 @@ fn main() { [`enum`][enum], [`Option`][option], and the [RFC][while_let_rfc] -[enum]: custom_types/enum.html -[option]: std/option.html +[enum]: ../custom_types/enum.md +[option]: ../std/option.md [while_let_rfc]: https://github.com/rust-lang/rfcs/pull/214 diff --git a/src/fn/closures/anonymity.md b/src/fn/closures/anonymity.md index 5e6840c9b4..7008a446b8 100644 --- a/src/fn/closures/anonymity.md +++ b/src/fn/closures/anonymity.md @@ -49,7 +49,7 @@ fn main() { [A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] -[generics]: generics.html +[generics]: ../../generics.md [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index 00f500b591..36468782f3 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -97,5 +97,5 @@ fn main() { [`Box`][box] and [`std::mem::drop`][drop] -[box]: std/box.html +[box]: ../../std/box.md [drop]: https://doc.rust-lang.org/std/mem/fn.drop.html diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index 87fe26f6f3..0810b281ac 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -46,8 +46,8 @@ fn main() { [Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. -[box]: std/box.html +[box]: ../../std/box.md [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html -[generics]: generics.html +[generics]: ../../generics.md diff --git a/src/generics.md b/src/generics.md index 641e0cf0ae..d1ecca5574 100644 --- a/src/generics.md +++ b/src/generics.md @@ -60,5 +60,5 @@ fn main() { [`struct`s][structs] -[structs]: custom_types/structs.html +[structs]: custom_types/structs.md [camelcase]: https://en.wikipedia.org/wiki/CamelCase diff --git a/src/generics/assoc_items/the_problem.md b/src/generics/assoc_items/the_problem.md index dca8f9b33f..bc6f7636b1 100644 --- a/src/generics/assoc_items/the_problem.md +++ b/src/generics/assoc_items/the_problem.md @@ -63,5 +63,5 @@ fn main() { [`struct`s][structs], and [`trait`s][traits] -[structs]: custom_types/structs.html -[traits]: trait.html +[structs]: ../../custom_types/structs.md +[traits]: ../../trait.md diff --git a/src/generics/bounds.md b/src/generics/bounds.md index ca9496013c..86e54e670c 100644 --- a/src/generics/bounds.md +++ b/src/generics/bounds.md @@ -74,8 +74,8 @@ some cases to be more expressive. [`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] -[fmt]: hello/print.html -[methods]: fn/methods.html -[structs]: custom_types/structs.html -[traits]: trait.html -[where]: generics/where.html +[fmt]: ../hello/print.md +[methods]: ../fn/methods.md +[structs]: ../custom_types/structs.md +[traits]: ../trait.md +[where]: ../generics/where.md diff --git a/src/generics/bounds/testcase_empty.md b/src/generics/bounds/testcase_empty.md index 9e0a850af8..df4904a3d5 100644 --- a/src/generics/bounds/testcase_empty.md +++ b/src/generics/bounds/testcase_empty.md @@ -40,4 +40,4 @@ fn main() { [eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html [ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html -[traits]: trait.html +[traits]: ../../trait.md diff --git a/src/generics/gen_fn.md b/src/generics/gen_fn.md index 3c8b2f9528..264057687d 100644 --- a/src/generics/gen_fn.md +++ b/src/generics/gen_fn.md @@ -55,5 +55,5 @@ fn main() { [functions][fn] and [`struct`s][structs] -[fn]: fn.html -[structs]: custom_types/structs.html +[fn]: ../fn.md +[structs]: ../custom_types/structs.md diff --git a/src/generics/gen_trait.md b/src/generics/gen_trait.md index adde475b42..6847dfea81 100644 --- a/src/generics/gen_trait.md +++ b/src/generics/gen_trait.md @@ -41,5 +41,5 @@ fn main() { [`Drop`][Drop], [`struct`][structs], and [`trait`][traits] [Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html -[structs]: custom_types/structs.html -[traits]: trait.html +[structs]: ../custom_types/structs.md +[traits]: ../trait.md diff --git a/src/generics/impl.md b/src/generics/impl.md index f5b4c44fd9..6410739a67 100644 --- a/src/generics/impl.md +++ b/src/generics/impl.md @@ -46,7 +46,7 @@ fn main() { [functions returning references][fn], [`impl`][methods], and [`struct`][structs] -[fn]: scope/lifetime/fn.html -[methods]: fn/methods.html +[fn]: ../scope/lifetime/fn.md +[methods]: ../fn/methods.md [specialization_plans]: https://blog.rust-lang.org/2015/05/11/traits.html#the-future -[structs]: custom_types/structs.html +[structs]: ../custom_types/structs.md diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md index c563282bcb..5f51a6c24b 100644 --- a/src/generics/multi_bounds.md +++ b/src/generics/multi_bounds.md @@ -33,5 +33,5 @@ fn main() { [`std::fmt`][fmt] and [`trait`s][traits] -[fmt]: hello/print.html -[traits]: trait.html +[fmt]: ../hello/print.md +[traits]: ../trait.md diff --git a/src/generics/new_types.md b/src/generics/new_types.md index a77282ef8a..ccbbbb03cf 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -54,5 +54,5 @@ fn main() { [`structs`][struct] -[struct]: custom_types/structs.html +[struct]: ../custom_types/structs.md diff --git a/src/generics/phantom.md b/src/generics/phantom.md index 7e9d7f5f04..59cf125d11 100644 --- a/src/generics/phantom.md +++ b/src/generics/phantom.md @@ -57,7 +57,7 @@ fn main() { [Derive], [struct], and [TupleStructs] -[Derive]: trait/derive.html -[struct]: custom_types/structs.html -[TupleStructs]: custom_types/structs.html +[Derive]: ../trait/derive.md +[struct]: ../custom_types/structs.md +[TupleStructs]: ../custom_types/structs.md [std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/src/generics/phantom/testcase_units.md b/src/generics/phantom/testcase_units.md index 52480316f7..00f59fe2de 100644 --- a/src/generics/phantom/testcase_units.md +++ b/src/generics/phantom/testcase_units.md @@ -77,12 +77,12 @@ fn main() { [Borrowing (`&`)], [Bounds (`X: Y`)], [enum], [impl & self], [Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. -[Borrowing (`&`)]: scope/borrow.html -[Bounds (`X: Y`)]: generics/bounds.html -[enum]: custom_types/enum.html -[impl & self]: fn/methods.html -[Overloading]: trait/ops.html -[ref]: scope/borrow/ref.html -[Traits (`X for Y`)]: trait.html -[TupleStructs]: custom_types/structs.html +[Borrowing (`&`)]: ../../scope/borrow.md +[Bounds (`X: Y`)]: ../../generics/bounds.md +[enum]: ../../custom_types/enum.md +[impl & self]: ../../fn/methods.md +[Overloading]: ../../trait/ops.md +[ref]: ../../scope/borrow/ref.md +[Traits (`X for Y`)]: ../../trait.md +[TupleStructs]: ../../custom_types/structs.md [std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html diff --git a/src/generics/where.md b/src/generics/where.md index 89da6de87c..f35f03f928 100644 --- a/src/generics/where.md +++ b/src/generics/where.md @@ -50,6 +50,6 @@ fn main() { [RFC][where], [`struct`][struct], and [`trait`][trait] -[struct]: custom_types/structs.html -[trait]: trait.html +[struct]: ../custom_types/structs.md +[trait]: ../trait.md [where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md diff --git a/src/hello.md b/src/hello.md index 22a4de7f7e..2a8d3153f3 100644 --- a/src/hello.md +++ b/src/hello.md @@ -46,4 +46,4 @@ Hello World! I'm a Rustacean! ``` -[macros]: macros.html +[macros]: macros.md diff --git a/src/hello/comment.md b/src/hello/comment.md index dc4a9dca09..8cd1ccf553 100644 --- a/src/hello/comment.md +++ b/src/hello/comment.md @@ -48,4 +48,4 @@ fn main() { [Library documentation][docs] -[docs]: meta/doc.html +[docs]: ../meta/doc.md diff --git a/src/hello/print.md b/src/hello/print.md index c335493bd3..495f3f2061 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -86,9 +86,9 @@ Implementing the `fmt::Display` trait automagically implements the and [`traits`][traits] [fmt]: https://doc.rust-lang.org/std/fmt/ -[macros]: macros.html -[string]: std/str.html -[structs]: custom_types/structs.html -[traits]: trait.html +[macros]: ../macros.md +[string]: ../std/str.md +[structs]: ../custom_types/structs.md +[traits]: ../trait.md [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html -[convert]: conversion/string.html +[convert]: ../conversion/string.md diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index 0173e35794..05df667f0d 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -78,7 +78,7 @@ One can manually implement `fmt::Display` to control the display. and [`struct`][structs] [attributes]: https://doc.rust-lang.org/reference/attributes.html -[derive]: trait/derive.html +[derive]: ../../trait/derive.md [fmt]: https://doc.rust-lang.org/std/fmt/ -[structs]: custom_types/structs.html +[structs]: ../../custom_types/structs.md diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 28f838dd39..55ed8702ad 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -121,9 +121,9 @@ Debug: Complex { real: 3.3, imag: 7.2 } [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] -[derive]: trait/derive.html +[derive]: ../../trait/derive.md [fmt]: https://doc.rust-lang.org/std/fmt/ -[macros]: macros.html -[structs]: custom_types/structs.html -[traits]: trait.html -[use]: mod/use.html +[macros]: ../../macros.md +[structs]: ../../custom_types/structs.md +[traits]: ../../trait.md +[use]: ../../mod/use.md diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index 87301ba58b..c44c022c62 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -71,9 +71,9 @@ Try changing the program so that the index of each element in the vector is also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], [`?`][q_mark], and [`vec!`][vec] -[for]: flow_control/for.html -[result]: std/result.html -[ref]: scope/borrow/ref.html -[struct]: custom_types/structs.html -[q_mark]: std/result/question_mark.html -[vec]: std/vec.html +[for]: ../../../flow_control/for.md +[result]: ../../../std/result.md +[ref]: ../../../scope/borrow/ref.md +[struct]: ../../../custom_types/structs.md +[q_mark]: ../../../std/result/question_mark.md +[vec]: ../../../std/vec.md diff --git a/src/index.md b/src/index.md index ad7024a516..fecc1906aa 100644 --- a/src/index.md +++ b/src/index.md @@ -11,53 +11,53 @@ Additionally for the curious, you can also [check out the source code for this s Now let's begin! -- [Hello World](hello.html) - Start with a traditional Hello World program. +- [Hello World](hello.md) - Start with a traditional Hello World program. -- [Primitives](primitives.html) - Learn about signed integers, unsigned integers and other primitives. +- [Primitives](primitives.md) - Learn about signed integers, unsigned integers and other primitives. -- [Custom Types](custom_types.html) - `struct` and `enum`. +- [Custom Types](custom_types.md) - `struct` and `enum`. -- [Variable Bindings](variable_bindings.html) - mutable bindings, scope, shadowing. +- [Variable Bindings](variable_bindings.md) - mutable bindings, scope, shadowing. -- [Types](types.html) - Learn about changing and defining types. +- [Types](types.md) - Learn about changing and defining types. -- [Conversion](conversion.html) +- [Conversion](conversion.md) -- [Expressions](expression.html) +- [Expressions](expression.md) -- [Flow of Control](flow_control.html) - `if`/`else`, `for`, and others. +- [Flow of Control](flow_control.md) - `if`/`else`, `for`, and others. -- [Functions](fn.html) - Learn about Methods, Closures and High Order Functions. +- [Functions](fn.md) - Learn about Methods, Closures and High Order Functions. -- [Modules](mod.html) - Organize code using modules +- [Modules](mod.md) - Organize code using modules -- [Crates](crates.html) - A crate is a compilation unit in Rust. Learn to create a library. +- [Crates](crates.md) - A crate is a compilation unit in Rust. Learn to create a library. -- [Cargo](cargo.html) - Go through some basic features of the official Rust package management tool. +- [Cargo](cargo.md) - Go through some basic features of the official Rust package management tool. -- [Attributes](attribute.html) - An attribute is metadata applied to some module, crate or item. +- [Attributes](attribute.md) - An attribute is metadata applied to some module, crate or item. -- [Generics](generics.html) - Learn about writing a function or data type which can work for multiple types of arguments. +- [Generics](generics.md) - Learn about writing a function or data type which can work for multiple types of arguments. -- [Scoping rules](scope.html) - Scopes play an important part in ownership, borrowing, and lifetimes. +- [Scoping rules](scope.md) - Scopes play an important part in ownership, borrowing, and lifetimes. -- [Traits](trait.html) - A trait is a collection of methods defined for an unknown type: `Self` +- [Traits](trait.md) - A trait is a collection of methods defined for an unknown type: `Self` -- [Macros](macros.html) +- [Macros](macros.md) -- [Error handling](error.html) - Learn Rust way of handling failures. +- [Error handling](error.md) - Learn Rust way of handling failures. -- [Std library types](std.html) - Learn about some custom types provided by `std` library. +- [Std library types](std.md) - Learn about some custom types provided by `std` library. -- [Std misc](std_misc.html) - More custom types for file handling, threads. +- [Std misc](std_misc.md) - More custom types for file handling, threads. -- [Testing](testing.html) - All sorts of testing in Rust. +- [Testing](testing.md) - All sorts of testing in Rust. -- [Unsafe Operations](unsafe.html) +- [Unsafe Operations](unsafe.md) -- [Compatibility](compatibility.html) +- [Compatibility](compatibility.md) -- [Meta](meta.html) - Documentation, Benchmarking. +- [Meta](meta.md) - Documentation, Benchmarking. [rust]: https://www.rust-lang.org/ diff --git a/src/macros/syntax.md b/src/macros/syntax.md index 16082586f0..d00e2695c0 100644 --- a/src/macros/syntax.md +++ b/src/macros/syntax.md @@ -7,6 +7,6 @@ There are three basic ideas: - [Overloading][overloading] - [Repetition][repetition] -[designators]: macros/designators.html -[overloading]: macros/overload.html -[repetition]: macros/repeat.html +[designators]: designators.md +[overloading]: overload.md +[repetition]: repeat.md diff --git a/src/mod/split.md b/src/mod/split.md index 703b915ae9..a7d20aedac 100644 --- a/src/mod/split.md +++ b/src/mod/split.md @@ -93,4 +93,4 @@ called `my::indirect_access()`, that called `my::nested::function()` ``` -[visibility]: mod/visibility.html +[visibility]: visibility.md diff --git a/src/mod/struct_visibility.md b/src/mod/struct_visibility.md index e10c526e9a..e7359413c7 100644 --- a/src/mod/struct_visibility.md +++ b/src/mod/struct_visibility.md @@ -55,5 +55,5 @@ fn main() { [generics][generics] and [methods][methods] -[generics]: generics.html -[methods]: fn/methods.html \ No newline at end of file +[generics]: ../generics.md +[methods]: ../fn/methods.md \ No newline at end of file diff --git a/src/primitives.md b/src/primitives.md index 14de0d74eb..dfa75068bc 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -58,6 +58,6 @@ fn main() { [the `std` library][std], [`mut`][mut], [inference], and [shadowing] [std]: https://doc.rust-lang.org/std/ -[mut]: variable_bindings/mut.html -[inference]: types/inference.html -[shadowing]: variable_bindings/scope.html +[mut]: variable_bindings/mut.md +[inference]: types/inference.md +[shadowing]: variable_bindings/scope.md diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index 253aa6fc26..7e29ef22c7 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -94,4 +94,4 @@ fn main() { ( 1.2 2.2 ) ``` -[print_display]: hello/print/print_display.html +[print_display]: ../hello/print/print_display.md diff --git a/src/scope/borrow/mut.md b/src/scope/borrow/mut.md index e9082b135b..62119bb483 100644 --- a/src/scope/borrow/mut.md +++ b/src/scope/borrow/mut.md @@ -56,4 +56,4 @@ fn main() { ### See also: [`static`][static] -[static]: scope/lifetime/static_lifetime.html +[static]: ../lifetime/static_lifetime.md diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md index 89c1279183..ebd7b69017 100644 --- a/src/scope/lifetime/explicit.md +++ b/src/scope/lifetime/explicit.md @@ -69,7 +69,7 @@ fn main() { [generics][generics] and [closures][closures] -[anonymity]: fn/closures/anonymity.html -[closures]: fn/closures.html -[elision]: scope/lifetime/elision.html -[generics]: generics.html +[anonymity]: ../../fn/closures/anonymity.md +[closures]: ../../fn/closures.md +[elision]: elision.md +[generics]: ../../generics.md diff --git a/src/scope/lifetime/fn.md b/src/scope/lifetime/fn.md index 64a1f5f7eb..6c5c8afe60 100644 --- a/src/scope/lifetime/fn.md +++ b/src/scope/lifetime/fn.md @@ -59,5 +59,5 @@ fn main() { [functions][fn] -[elision]: scope/lifetime/elision.html -[fn]: fn.html +[elision]: elision.md +[fn]: fn.md diff --git a/src/scope/lifetime/lifetime_bounds.md b/src/scope/lifetime/lifetime_bounds.md index 8df5f96125..3d635bde1f 100644 --- a/src/scope/lifetime/lifetime_bounds.md +++ b/src/scope/lifetime/lifetime_bounds.md @@ -48,6 +48,6 @@ fn main() { [generics][generics], [bounds in generics][bounds], and [multiple bounds in generics][multibounds] -[generics]: generics.html -[bounds]: generics/bounds.html -[multibounds]: generics/multi_bounds.html +[generics]: ../../generics.md +[bounds]: ../../generics/bounds.md +[multibounds]: ../../generics/multi_bounds.md diff --git a/src/scope/lifetime/methods.md b/src/scope/lifetime/methods.md index c7317c833a..1e1eb96f47 100644 --- a/src/scope/lifetime/methods.md +++ b/src/scope/lifetime/methods.md @@ -25,4 +25,4 @@ fn main() { [methods] -[methods]: fn/methods.html +[methods]: ../../fn/methods.md diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index 917b6b7959..46d81117c8 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -49,4 +49,4 @@ fn main() { [`'static` constants][static_const] -[static_const]: custom_types/constants.html \ No newline at end of file +[static_const]: ../../custom_types/constants.md \ No newline at end of file diff --git a/src/scope/lifetime/struct.md b/src/scope/lifetime/struct.md index 3b33da3ee6..aca0bfe622 100644 --- a/src/scope/lifetime/struct.md +++ b/src/scope/lifetime/struct.md @@ -43,4 +43,4 @@ fn main() { [`struct`s][structs] -[structs]: custom_types/structs.html +[structs]: ../../custom_types/structs.md diff --git a/src/scope/lifetime/trait.md b/src/scope/lifetime/trait.md index c0808ae09a..0f56f5b4c1 100644 --- a/src/scope/lifetime/trait.md +++ b/src/scope/lifetime/trait.md @@ -30,4 +30,4 @@ fn main() { [`trait`s][trait] -[trait]: trait.html +[trait]: ../../trait.md diff --git a/src/scope/move.md b/src/scope/move.md index 84372af8f2..0433e8ac1a 100644 --- a/src/scope/move.md +++ b/src/scope/move.md @@ -57,4 +57,4 @@ fn main() { } ``` -[references]: flow_control/match/destructuring/destructure_pointers.html +[references]: ../flow_control/match/destructuring/destructure_pointers.md diff --git a/src/scope/raii.md b/src/scope/raii.md index d5c00a5b97..2b2071707e 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -91,6 +91,6 @@ fn main() { [Box][box] [raii]: https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization -[box]: std/box.html +[box]: ../std/box.md [valgrind]: http://valgrind.org/info/ [`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html diff --git a/src/std.md b/src/std.md index debfc73f49..8863c788ae 100644 --- a/src/std.md +++ b/src/std.md @@ -13,5 +13,5 @@ the `primitives`. Some of these include: [primitives] and [the std library][std] -[primitives]: primitives.html +[primitives]: primitives.md [std]: https://doc.rust-lang.org/std/ diff --git a/src/std_misc.md b/src/std_misc.md index 5106b934de..ac9c57864f 100644 --- a/src/std_misc.md +++ b/src/std_misc.md @@ -13,5 +13,5 @@ These expand beyond what the [primitives] provide. [primitives] and [the std library][std] -[primitives]: primitives.html +[primitives]: primitives.md [std]: https://doc.rust-lang.org/std/ diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index 42eccf3ef5..0374c5a205 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -143,4 +143,4 @@ fn cat(path: &Path) -> io::Result { [`cfg!`][cfg] -[cfg]: attribute/cfg.html +[cfg]: ../attribute/cfg.md diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 6de19e0931..9efc34a87f 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -140,13 +140,13 @@ defined by a static constant at the beginning of the program. * [unwrap vs. expect][unwrap] * [enumerate][enumerate] -[thread]: std_misc/threads.html -[vectors]: std/vec.html -[iterators]: trait/iter.html +[thread]: ../threads.md +[vectors]: ../../std/vec.md +[iterators]: ../../trait/iter.md [destructuring]: https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html#destructuring-to-break-apart-values -[closures]: fn/closures.html -[move]: scope/move.html +[closures]: ../../fn/closures.md +[move]: ../../scope/move.md [move_closure]: https://doc.rust-lang.org/book/ch13-01-closures.html#closures-can-capture-their-environment [turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect -[unwrap]: error/option_unwrap.html +[unwrap]: ../../error/option_unwrap.md [enumerate]: https://doc.rust-lang.org/book/loops.html#enumerate diff --git a/src/testing.md b/src/testing.md index b94462474e..6de0ca63fd 100644 --- a/src/testing.md +++ b/src/testing.md @@ -18,9 +18,9 @@ Also Rust has support for specifying additional dependencies for tests: * [The Book][doc-testing] chapter on testing * [API Guidelines][doc-nursery] on doc-testing -[unit]: testing/unit_testing.html -[doc]: testing/doc_testing.html -[integration]: testing/integration_testing.html -[dev-dependencies]: testing/dev_dependencies.html +[unit]: testing/unit_testing.md +[doc]: testing/doc_testing.md +[integration]: testing/integration_testing.md +[dev-dependencies]: testing/dev_dependencies.md [doc-testing]: https://doc.rust-lang.org/book/ch11-00-testing.html [doc-nursery]: https://rust-lang-nursery.github.io/api-guidelines/documentation.html diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index ba66ff0242..d0e5122b51 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -83,5 +83,5 @@ fn test_add() { Modules with common code follow the ordinary [modules][mod] rules, so it's ok to create common module as `tests/common/mod.rs`. -[unit]: testing/unit_testing.html -[mod]: mod.html +[unit]: unit_testing.md +[mod]: ../mod.md diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index 252577f0ef..a6060e9c0d 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -224,7 +224,7 @@ running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` -[attribute]: attribute.html -[panic]: std/panic.html -[macros]: macros.html -[mod]: mod.html +[attribute]: ../attribute.md +[panic]: ../std/panic.md +[macros]: ../macros.md +[mod]: ../mod.md diff --git a/src/trait/derive.md b/src/trait/derive.md index 4ef87cdb38..4769efe627 100644 --- a/src/trait/derive.md +++ b/src/trait/derive.md @@ -64,7 +64,7 @@ fn main() { ### See also: [`derive`][derive] -[attribute]: attribute.html +[attribute]: ../attribute.md [eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html [partial-eq]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html [ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html diff --git a/src/types.md b/src/types.md index 04088a96f0..1d3b50aaba 100644 --- a/src/types.md +++ b/src/types.md @@ -7,7 +7,7 @@ user defined types. The following sections cover: * Using [type inference] * [Aliasing] types -[Casting]: types/cast.html -[literals]: types/literals.html -[type inference]: types/inference.html -[Aliasing]: types/alias.html +[Casting]: types/cast.md +[literals]: types/literals.md +[type inference]: types/inference.md +[Aliasing]: types/alias.md diff --git a/src/types/alias.md b/src/types/alias.md index 3c3bed0162..c839f53213 100644 --- a/src/types/alias.md +++ b/src/types/alias.md @@ -33,4 +33,4 @@ is an alias for the `Result` type. ### See also: -[Attributes](attribute.html) \ No newline at end of file +[Attributes](../attribute.md) \ No newline at end of file diff --git a/src/types/literals.md b/src/types/literals.md index db2b7323f2..78aa67fbe3 100644 --- a/src/types/literals.md +++ b/src/types/literals.md @@ -38,6 +38,6 @@ yet, here's a brief explanation for the impatient readers: is defined in the `std` *crate*. For more details, see [modules][mod] and [crates][crate]. -[borrow]: scope/borrow.html -[mod]: mod.html -[crate]: crates.html +[borrow]: ../scope/borrow.md +[mod]: ../mod.md +[crate]: ../crates.md diff --git a/src/unsafe.md b/src/unsafe.md index 742762c279..1eeec6ba35 100644 --- a/src/unsafe.md +++ b/src/unsafe.md @@ -8,7 +8,7 @@ things that unsafe is used for: * dereferencing raw pointers * calling functions or methods which are `unsafe` (including calling a function - over FFI, see [a previous chapter](std_misc/ffi.html) of the book) + over FFI, see [a previous chapter](std_misc/ffi.md) of the book) * accessing or modifying static mutable variables * implementing unsafe traits From 22fa894f9a53a48909cd6c0d593e20109a3c4147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 11 Jun 2019 15:55:43 +0200 Subject: [PATCH 0915/1122] Add Cargo comment to the `try!` macro example. In Rust "2018", `try!` macro is deprecated, and `try` is a reserved keyword. If you're using Cargo to compile the code using this syntax, you'll get an error message. To fix it, you need to change the value of the `edition` field in the `Cargo.toml` file back to "2015". --- src/error/result/enter_question_mark.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index ff4be176f0..5fb9ccfb02 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -44,6 +44,9 @@ at older code. The same `multiply` function from the previous example would look like this using `try!`: ```rust,editable +// To compile and run this example without errors, while using Cargo, change the value +// of the `edition` field, in the `[package]` section of the `Cargo.toml` file, to "2015". + use std::num::ParseIntError; fn multiply(first_number_str: &str, second_number_str: &str) -> Result { From 6216eda1b7a56371ea24bcc8e47afb7fc47af4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 14 Jun 2019 00:14:24 +0200 Subject: [PATCH 0916/1122] Remove unused import. --- src/error/multiple_error_types/reenter_question_mark.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index 74bcddcca1..bf93e8a42d 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -25,7 +25,6 @@ Here, we rewrite the previous example using `?`. As a result, the ```rust,editable use std::error; use std::fmt; -use std::num::ParseIntError; // Change the alias to `Box`. type Result = std::result::Result>; From e32aefa76ce01a3897719599f7ff7f3a1922cc04 Mon Sep 17 00:00:00 2001 From: ironyman Date: Thu, 13 Jun 2019 22:26:49 -0700 Subject: [PATCH 0917/1122] Fix typo --- src/custom_types/enum.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index 51683fb8e3..5eae819adc 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -16,7 +16,7 @@ enum WebEvent { // like tuple structs, KeyPress(char), Paste(String), - // or like structures. + // or c-like structures. Click { x: i64, y: i64 }, } From 3813838d45295f5397458ca2fdb51f5facfc5930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Sun, 16 Jun 2019 00:33:40 +0200 Subject: [PATCH 0918/1122] Update `macro_rules!' formatting. In accordance to the default behavior of `rust-fmt`, most of plain parentheses used in `macro_rules!` definitions, have been replaced by curly braces. --- src/macros.md | 4 ++-- src/macros/designators.md | 8 ++++---- src/macros/dry.md | 10 +++++----- src/macros/overload.md | 8 ++++---- src/macros/repeat.md | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/macros.md b/src/macros.md index 0b27fc9935..ac727f463f 100644 --- a/src/macros.md +++ b/src/macros.md @@ -14,10 +14,10 @@ Macros are created using the `macro_rules!` macro. // This is a simple macro named `say_hello`. macro_rules! say_hello { // `()` indicates that the macro takes no argument. - () => ( + () => { // The macro will expand into the contents of this block. println!("Hello!"); - ) + }; } fn main() { diff --git a/src/macros/designators.md b/src/macros/designators.md index b2230ef420..78183030a8 100644 --- a/src/macros/designators.md +++ b/src/macros/designators.md @@ -8,13 +8,13 @@ macro_rules! create_function { // This macro takes an argument of designator `ident` and // creates a function named `$func_name`. // The `ident` designator is used for variable/function names. - ($func_name:ident) => ( + ($func_name:ident) => { fn $func_name() { // The `stringify!` macro converts an `ident` into a string. println!("You called {:?}()", stringify!($func_name)); } - ) + }; } // Create functions named `foo` and `bar` with the above macro. @@ -25,12 +25,12 @@ macro_rules! print_result { // This macro takes an expression of type `expr` and prints // it as a string along with its result. // The `expr` designator is used for expressions. - ($expression:expr) => ( + ($expression:expr) => { // `stringify!` will convert the expression *as it is* into a string. println!("{:?} = {:?}", stringify!($expression), $expression); - ) + }; } fn main() { diff --git a/src/macros/dry.md b/src/macros/dry.md index ffa8250687..a8c06112ca 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -10,18 +10,18 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for // operators and tokens. - ($a:ident, $b:ident, $func:ident, $op:tt) => ( + ($a:ident, $b:ident, $func:ident, $op:tt) => { assert!($a.len() == $b.len(), "{:?}: dimension mismatch: {:?} {:?} {:?}", stringify!($func), ($a.len(),), stringify!($op), ($b.len(),)); - ) + }; } macro_rules! op { - ($func:ident, $bound:ident, $op:tt, $method:ident) => ( + ($func:ident, $bound:ident, $op:tt, $method:ident) => { fn $func + Copy>(xs: &mut Vec, ys: &Vec) { assert_equal_len!(xs, ys, $func, $op); @@ -30,7 +30,7 @@ macro_rules! op { // *x = x.$method(*y); } } - ) + }; } // Implement `add_assign`, `mul_assign`, and `sub_assign` functions. @@ -54,7 +54,7 @@ mod test { assert_eq!(x, z); } } - } + }; } // Test `add_assign`, `mul_assign`, and `sub_assign`. diff --git a/src/macros/overload.md b/src/macros/overload.md index 6415e2e4dc..84d341a56a 100644 --- a/src/macros/overload.md +++ b/src/macros/overload.md @@ -9,19 +9,19 @@ In that regard, `macro_rules!` can work similarly to a match block: macro_rules! test { // Arguments don't need to be separated by a comma. // Any template can be used! - ($left:expr; and $right:expr) => ( + ($left:expr; and $right:expr) => { println!("{:?} and {:?} is {:?}", stringify!($left), stringify!($right), $left && $right) - ); + }; // ^ each arm must end with a semicolon. - ($left:expr; or $right:expr) => ( + ($left:expr; or $right:expr) => { println!("{:?} or {:?} is {:?}", stringify!($left), stringify!($right), $left || $right) - ); + }; } fn main() { diff --git a/src/macros/repeat.md b/src/macros/repeat.md index 2b00387972..a3431ef51c 100644 --- a/src/macros/repeat.md +++ b/src/macros/repeat.md @@ -22,7 +22,7 @@ macro_rules! find_min { fn main() { println!("{}", find_min!(1u32)); - println!("{}", find_min!(1u32 + 2 , 2u32)); + println!("{}", find_min!(1u32 + 2, 2u32)); println!("{}", find_min!(5u32, 2u32 * 3, 4u32)); } ``` \ No newline at end of file From 2c743c5896815aee2faa885e5298d82c67727139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 18 Jun 2019 14:05:53 +0200 Subject: [PATCH 0919/1122] Reword stack/heap memory allocation description. Changed all the instances of `in the heap/stack` into `on the heap/stack`. This form is widely accepted within the industry, and consistent with the "The Rust Programming Language" book. --- src/std/box.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/std/box.md b/src/std/box.md index 64856d7aa7..ede2b81429 100644 --- a/src/std/box.md +++ b/src/std/box.md @@ -1,9 +1,9 @@ # Box, stack and heap All values in Rust are stack allocated by default. Values can be *boxed* -(allocated in the heap) by creating a `Box`. A box is a smart pointer to a +(allocated on the heap) by creating a `Box`. A box is a smart pointer to a heap allocated value of type `T`. When a box goes out of scope, its destructor -is called, the inner object is destroyed, and the memory in the heap is freed. +is called, the inner object is destroyed, and the memory on the heap is freed. Boxed values can be dereferenced using the `*` operator; this removes one layer of indirection. @@ -29,7 +29,7 @@ fn origin() -> Point { } fn boxed_origin() -> Box { - // Allocate this point in the heap, and return a pointer to it + // Allocate this point on the heap, and return a pointer to it Box::new(Point { x: 0.0, y: 0.0 }) } @@ -54,22 +54,22 @@ fn main() { // Double indirection let box_in_a_box: Box> = Box::new(boxed_origin()); - println!("Point occupies {} bytes in the stack", + println!("Point occupies {} bytes on the stack", mem::size_of_val(&point)); - println!("Rectangle occupies {} bytes in the stack", + println!("Rectangle occupies {} bytes on the stack", mem::size_of_val(&rectangle)); // box size = pointer size - println!("Boxed point occupies {} bytes in the stack", + println!("Boxed point occupies {} bytes on the stack", mem::size_of_val(&boxed_point)); - println!("Boxed rectangle occupies {} bytes in the stack", + println!("Boxed rectangle occupies {} bytes on the stack", mem::size_of_val(&boxed_rectangle)); - println!("Boxed box occupies {} bytes in the stack", + println!("Boxed box occupies {} bytes on the stack", mem::size_of_val(&box_in_a_box)); // Copy the data contained in `boxed_point` into `unboxed_point` let unboxed_point: Point = *boxed_point; - println!("Unboxed point occupies {} bytes in the stack", + println!("Unboxed point occupies {} bytes on the stack", mem::size_of_val(&unboxed_point)); } ``` \ No newline at end of file From 7f797da7c9da536196ab3f0ae8aa5b1a45010674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 18 Jun 2019 14:15:37 +0200 Subject: [PATCH 0920/1122] Fix inconsistent use of `=` sign in the comment. Changed a single `=` (assignment) into `==` (equality), which was clearly the author's original intention. --- src/std/box.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/box.md b/src/std/box.md index ede2b81429..8d45e1a44e 100644 --- a/src/std/box.md +++ b/src/std/box.md @@ -59,7 +59,7 @@ fn main() { println!("Rectangle occupies {} bytes on the stack", mem::size_of_val(&rectangle)); - // box size = pointer size + // box size == pointer size println!("Boxed point occupies {} bytes on the stack", mem::size_of_val(&boxed_point)); println!("Boxed rectangle occupies {} bytes on the stack", From fe7e846167e7071a77f1765d7a490147a7b4f45a Mon Sep 17 00:00:00 2001 From: adispring Date: Fri, 21 Jun 2019 10:44:26 +0800 Subject: [PATCH 0921/1122] [typo] Note, that it is -> Note that, it is --- src/fn/diverging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/diverging.md b/src/fn/diverging.md index 6cd63a0d36..19cf27c080 100644 --- a/src/fn/diverging.md +++ b/src/fn/diverging.md @@ -9,7 +9,7 @@ fn foo() -> ! { ``` As opposed to all the other types, this one cannot be instantiated, because the -set of all possible values this type can have is empty. Note, that it is +set of all possible values this type can have is empty. Note that, it is different from the `()` type, which has exactly one possible value. For example, this function returns as usual, although there is no information From 4a5e2f002a7beebd263803491bd76a075f3e043f Mon Sep 17 00:00:00 2001 From: Rafael Alves Sa Date: Sat, 22 Jun 2019 19:23:10 +0100 Subject: [PATCH 0922/1122] Update enter_question_mark.md --- src/error/result/enter_question_mark.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/result/enter_question_mark.md b/src/error/result/enter_question_mark.md index 5fb9ccfb02..8101e3efd7 100644 --- a/src/error/result/enter_question_mark.md +++ b/src/error/result/enter_question_mark.md @@ -10,7 +10,7 @@ Upon finding an `Err`, there are two valid actions to take: 2. `return` because an `Err` means it cannot be handled `?` is *almost*[^†] exactly equivalent to an `unwrap` which `return`s -instead of `panic`s on `Err`s. Let's see how we can simplify the earlier +instead of `panic`king on `Err`s. Let's see how we can simplify the earlier example that used combinators: ```rust,editable From 3dadd5680723e2bc3779823459f0038136fdccd7 Mon Sep 17 00:00:00 2001 From: adispring Date: Tue, 25 Jun 2019 18:08:11 +0800 Subject: [PATCH 0923/1122] [typo] fix unit_testing wrong output --- src/testing/unit_testing.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index a6060e9c0d..8800ed2d03 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -200,10 +200,12 @@ mod tests { ```bash $ cargo test -running 1 test +running 3 tests test tests::ignored_test ... ignored +test tests::test_add ... ok +test tests::test_add_hundred ... ok -test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out +test result: ok. 2 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out Doc-tests tmp-ignore From f74f0582296e56a7ba5818e274438941fa593498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Thu, 27 Jun 2019 13:32:19 +0200 Subject: [PATCH 0924/1122] Use Field Init Shorthand in the `logon` struct. If a struct field, and variable used to initialize it, have the same name, there's no need to write them both. --- src/std/hash/alt_key_types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std/hash/alt_key_types.md b/src/std/hash/alt_key_types.md index 8b91a13277..ab94819b25 100644 --- a/src/std/hash/alt_key_types.md +++ b/src/std/hash/alt_key_types.md @@ -50,8 +50,8 @@ fn try_logon<'a>(accounts: &Accounts<'a>, println!("Attempting logon..."); let logon = Account { - username: username, - password: password, + username, + password, }; match accounts.get(&logon) { From 42917744011d9354ec9e26ecd1da059dffa565c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Thu, 27 Jun 2019 13:36:56 +0200 Subject: [PATCH 0925/1122] Use square brackets in `vec!` macro. It's the default behavior of `rust-fmt`, and it's consistent with the rest of examples from the book. --- src/std/hash/hashset.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std/hash/hashset.md b/src/std/hash/hashset.md index a7b3983d7e..63d5af8782 100644 --- a/src/std/hash/hashset.md +++ b/src/std/hash/hashset.md @@ -36,8 +36,8 @@ Try all of these in the following example: use std::collections::HashSet; fn main() { - let mut a: HashSet = vec!(1i32, 2, 3).into_iter().collect(); - let mut b: HashSet = vec!(2i32, 3, 4).into_iter().collect(); + let mut a: HashSet = vec![1i32, 2, 3].into_iter().collect(); + let mut b: HashSet = vec![2i32, 3, 4].into_iter().collect(); assert!(a.insert(4)); assert!(a.contains(&4)); From 935c57611f26f2b395528488d494e8bf1455ee77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:23:46 +0200 Subject: [PATCH 0926/1122] Add missing period. --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index a771d0613a..76870d9829 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -112,7 +112,7 @@ fn main() { } ``` -Want a string that's not UTF-8? (Remember, `str` and `String` must be valid UTF-8) +Want a string that's not UTF-8? (Remember, `str` and `String` must be valid UTF-8). Or maybe you want an array of bytes that's mostly text? Byte strings to the rescue! ```rust, editable From c94a6925277bdc678191bb7873e7a0d75cd3388f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:27:31 +0200 Subject: [PATCH 0927/1122] Reword a comment for clarity. --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index 76870d9829..776e186304 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -122,7 +122,7 @@ fn main() { // Note that this is not actually a &str let bytestring: &[u8; 20] = b"this is a bytestring"; - // Byte arrays don't have Display so printing them is a bit limited + // Byte arrays don't have the `Display` trait, so printing them is a bit limited println!("A bytestring: {:?}", bytestring); // Bytestrings can have byte escapes... From 9fbcf16bc85e476cdf2af62800400b6852059e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:32:37 +0200 Subject: [PATCH 0928/1122] Add missing quotes for the types in comments. --- src/std/str.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/std/str.md b/src/std/str.md index 776e186304..ed963d9649 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -119,7 +119,7 @@ Or maybe you want an array of bytes that's mostly text? Byte strings to the resc use std::str; fn main() { - // Note that this is not actually a &str + // Note that this is not actually a `&str` let bytestring: &[u8; 20] = b"this is a bytestring"; // Byte arrays don't have the `Display` trait, so printing them is a bit limited @@ -136,7 +136,7 @@ fn main() { let raw_bytestring = br"\u{211D} is not escaped here"; println!("{:?}", raw_bytestring); - // Converting a byte array to str can fail + // Converting a byte array to `str` can fail if let Ok(my_str) = str::from_utf8(raw_bytestring) { println!("And the same as text: '{}'", my_str); } @@ -147,7 +147,7 @@ fn main() { // Bytestrings don't have to be UTF-8 let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82"; // "ようこそ" in SHIFT-JIS - // But then they can't always be converted to str + // But then they can't always be converted to `str` match str::from_utf8(shift_jis) { Ok(my_str) => println!("Conversion successful: '{}'", my_str), Err(e) => println!("Conversion failed: {:?}", e), From ff273c4e7ad456b0f890c264d1f1d36c829a4764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:34:53 +0200 Subject: [PATCH 0929/1122] Fix inconsistend use of the `byte string` phrase. I have changed all instances of `bytestring` into `byte string`. The latter form seems to be the proper one. Language documentation also use `byte slice` naming, but I'm not sure it's a reference to the same thing, so I'm open to feedback from the community. --- src/std/str.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/std/str.md b/src/std/str.md index ed963d9649..5d366eea88 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -120,19 +120,19 @@ use std::str; fn main() { // Note that this is not actually a `&str` - let bytestring: &[u8; 20] = b"this is a bytestring"; + let bytestring: &[u8; 20] = b"this is a byte string"; // Byte arrays don't have the `Display` trait, so printing them is a bit limited - println!("A bytestring: {:?}", bytestring); + println!("A byte string: {:?}", bytestring); - // Bytestrings can have byte escapes... + // Byte strings can have byte escapes... let escaped = b"\x52\x75\x73\x74 as bytes"; // ...but no unicode escapes // let escaped = b"\u{211D} is not allowed"; println!("Some escaped bytes: {:?}", escaped); - // Raw bytestrings work just like raw strings + // Raw byte strings work just like raw strings let raw_bytestring = br"\u{211D} is not escaped here"; println!("{:?}", raw_bytestring); @@ -144,7 +144,7 @@ fn main() { let quotes = br#"You can also use "fancier" formatting, \ like with normal raw strings"#; - // Bytestrings don't have to be UTF-8 + // Byte strings don't have to be UTF-8 let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82"; // "ようこそ" in SHIFT-JIS // But then they can't always be converted to `str` From 44080b75fcc232031ff5bc1e2c15562a024278c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:45:23 +0200 Subject: [PATCH 0930/1122] Add `_` prefix to the unused variable name. --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index 5d366eea88..24e0cfc592 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -141,7 +141,7 @@ fn main() { println!("And the same as text: '{}'", my_str); } - let quotes = br#"You can also use "fancier" formatting, \ + let _quotes = br#"You can also use "fancier" formatting, \ like with normal raw strings"#; // Byte strings don't have to be UTF-8 From 94e91756b216a13ab7d84f0ffb66f2f09df88d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Fri, 28 Jun 2019 15:46:16 +0200 Subject: [PATCH 0931/1122] Fix array size bug introduced in previous commit. After changing `bytestring` into `byte string` in one of the byte string literals, I forgot to adjust the array size to compensate for an extra space. --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index 24e0cfc592..9f4d7105e1 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -120,7 +120,7 @@ use std::str; fn main() { // Note that this is not actually a `&str` - let bytestring: &[u8; 20] = b"this is a byte string"; + let bytestring: &[u8; 21] = b"this is a byte string"; // Byte arrays don't have the `Display` trait, so printing them is a bit limited println!("A byte string: {:?}", bytestring); From 581f2a149c1d3489a8c99cc00e8104b971fb9011 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Mon, 1 Jul 2019 23:43:56 +0300 Subject: [PATCH 0932/1122] added link to russian translation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 58bba9fabb..d4056e90ef 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Please see the [CONTRIBUTING.md] file for more details. * [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) * [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) * [French](https://github.com/Songbird0/FR_RBE) +* [Russian](https://github.com/ruRust/rust-by-example-ru) ## License From 5de708b3eb182b5d5ff532cdb461b35559869240 Mon Sep 17 00:00:00 2001 From: Yash Joshi Date: Wed, 3 Jul 2019 01:26:00 +0530 Subject: [PATCH 0933/1122] Fix: Automatically Typo --- src/hello/print.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index 495f3f2061..7b1b7ed41e 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -67,7 +67,7 @@ friendly fashion. Here, we used `fmt::Display `because the std library provides implementations for these types. To print text for custom types, more steps are required. -Implementing the `fmt::Display` trait automagically implements the +Implementing the `fmt::Display` trait automatically implements the [`ToString`] trait which allows us to [convert] the type to [`String`][string]. ### Activities From d33aa57f83d531bffe5ad3a8e73a140b380325e5 Mon Sep 17 00:00:00 2001 From: Chayoung You Date: Fri, 5 Jul 2019 15:26:30 +0900 Subject: [PATCH 0934/1122] Make `use` example runnable --- src/mod/use.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/use.md b/src/mod/use.md index 5f99138726..44cef988cc 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -19,7 +19,7 @@ fn main() { You can use the `as` keyword to bind imports to a different name: -```rust,editable,ignore +```rust,editable // Bind the `deeply::nested::function` path to `other_function`. use deeply::nested::function as other_function; From d87a683b1e80fdab174bcf0e7110c8dbf78da8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 9 Jul 2019 00:01:53 +0200 Subject: [PATCH 0935/1122] Change the description of a `Vec` type parameters. --- src/std/vec.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/std/vec.md b/src/std/vec.md index 6ba442251d..751031a912 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -2,10 +2,14 @@ Vectors are re-sizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time. A vector is represented using -3 words: a pointer to the data, its length, and its capacity. The capacity -indicates how much memory is reserved for the vector. The vector can grow as -long as the length is smaller than the capacity. When this threshold needs to -be surpassed, the vector is reallocated with a larger capacity. +3 parameters: +- pointer to the data +- length +- capacity + +The capacity indicates how much memory is reserved for the vector. The vector +can grow as long as the length is smaller than the capacity. When this threshold +needs to be surpassed, the vector is reallocated with a larger capacity. ```rust,editable,ignore,mdbook-runnable fn main() { From fcf3b68d1c068d6bbcf358fb1a9dd5aa68fffd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 9 Jul 2019 00:06:03 +0200 Subject: [PATCH 0936/1122] Change ambiguous description of `Vec::len` method Vector's `size` can be easily misinterpreted as its capacity or memory footprint. --- src/std/vec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std/vec.md b/src/std/vec.md index 751031a912..6e217fdf8e 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -30,8 +30,8 @@ fn main() { collected_iterator.push(0); // FIXME ^ Comment out this line - // The `len` method yields the current size of the vector - println!("Vector size: {}", xs.len()); + // The `len` method yields the number of elements currently stored in a vector + println!("Vector length: {}", xs.len()); // Indexing is done using the square brackets (indexing starts at 0) println!("Second element: {}", xs[1]); From 1ae475ff0305dc67484ce70cd117ea09425f7bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Tue, 9 Jul 2019 00:12:36 +0200 Subject: [PATCH 0937/1122] Remove unnecessary `mut` modifier. This was introduced unintentionally in #1178. The comments are clear, that the line number 16 should be commented out, in order to compile the example without errors. --- src/std/vec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/vec.md b/src/std/vec.md index 6e217fdf8e..f5cb1cae0c 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -14,7 +14,7 @@ needs to be surpassed, the vector is reallocated with a larger capacity. ```rust,editable,ignore,mdbook-runnable fn main() { // Iterators can be collected into vectors - let mut collected_iterator: Vec = (0..10).collect(); + let collected_iterator: Vec = (0..10).collect(); println!("Collected (0..10) into: {:?}", collected_iterator); // The `vec!` macro can be used to initialize a vector From 6262c5c6c91eb847e419b4d7dd479006ed811812 Mon Sep 17 00:00:00 2001 From: Homo Efficio Date: Sat, 13 Jul 2019 22:05:53 +0900 Subject: [PATCH 0938/1122] Changed mutable collected_iterator into immutable `collected_iterator` should be immutable in order for `collected_iterator.push(0)` to produce error. --- src/std/vec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/vec.md b/src/std/vec.md index 6ba442251d..07408fe5b9 100644 --- a/src/std/vec.md +++ b/src/std/vec.md @@ -10,7 +10,7 @@ be surpassed, the vector is reallocated with a larger capacity. ```rust,editable,ignore,mdbook-runnable fn main() { // Iterators can be collected into vectors - let mut collected_iterator: Vec = (0..10).collect(); + let collected_iterator: Vec = (0..10).collect(); println!("Collected (0..10) into: {:?}", collected_iterator); // The `vec!` macro can be used to initialize a vector From 97bbb59efe6b5f715b34f38cad94645e778c7bcd Mon Sep 17 00:00:00 2001 From: Austin W Keeton Date: Sun, 14 Jul 2019 18:02:18 -0500 Subject: [PATCH 0939/1122] Fix minor formatting inconsistencies. --- src/mod/visibility.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/visibility.md b/src/mod/visibility.md index 2c3ca8b89a..84840e43de 100644 --- a/src/mod/visibility.md +++ b/src/mod/visibility.md @@ -38,20 +38,20 @@ mod my_mod { // Functions declared using `pub(in path)` syntax are only visible // within the given path. `path` must be a parent or ancestor module pub(in crate::my_mod) fn public_function_in_my_mod() { - print!("called `my_mod::nested::public_function_in_my_mod()`, that\n > "); - public_function_in_nested() + print!("called `my_mod::nested::public_function_in_my_mod()`, that\n> "); + public_function_in_nested(); } // Functions declared using `pub(self)` syntax are only visible within // the current module, which is the same as leaving them private pub(self) fn public_function_in_nested() { - println!("called `my_mod::nested::public_function_in_nested"); + println!("called `my_mod::nested::public_function_in_nested()`"); } // Functions declared using `pub(super)` syntax are only visible within // the parent module pub(super) fn public_function_in_super_mod() { - println!("called my_mod::nested::public_function_in_super_mod"); + println!("called `my_mod::nested::public_function_in_super_mod()`"); } } @@ -64,7 +64,7 @@ mod my_mod { // pub(crate) makes functions visible only within the current crate pub(crate) fn public_function_in_crate() { - println!("called `my_mod::public_function_in_crate()"); + println!("called `my_mod::public_function_in_crate()`"); } // Nested modules follow the same rules for visibility From 223c50dd47125a3438080161e2a758836ee89bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Mon, 15 Jul 2019 19:53:12 +0200 Subject: [PATCH 0940/1122] Fix several shell output and code highlights. --- src/attribute/cfg/custom.md | 2 +- src/attribute/crate.md | 2 +- src/cargo/test.md | 12 ++++++------ src/crates/lib.md | 2 +- src/crates/link.md | 2 +- src/macros/dry.md | 2 +- src/meta/doc.md | 2 +- src/mod/split.md | 4 ++-- src/scope/raii.md | 2 +- src/std/panic.md | 2 +- src/std_misc/arg.md | 2 +- src/std_misc/arg/matching.md | 2 +- src/std_misc/file/create.md | 2 +- src/std_misc/file/open.md | 2 +- src/std_misc/file/read_lines.md | 2 +- src/std_misc/fs.md | 4 ++-- src/testing/dev_dependencies.md | 2 +- src/testing/doc_testing.md | 2 +- src/testing/integration_testing.md | 2 +- src/testing/unit_testing.md | 10 +++++----- 20 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/attribute/cfg/custom.md b/src/attribute/cfg/custom.md index 90b2a0ee2f..182d33654c 100644 --- a/src/attribute/cfg/custom.md +++ b/src/attribute/cfg/custom.md @@ -18,7 +18,7 @@ Try to run this to see what happens without the custom `cfg` flag. With the custom `cfg` flag: -```bash +```shell $ rustc --cfg some_condition custom.rs && ./custom condition met! ``` diff --git a/src/attribute/crate.md b/src/attribute/crate.md index 33674faaec..1539c63988 100644 --- a/src/attribute/crate.md +++ b/src/attribute/crate.md @@ -33,7 +33,7 @@ pub fn indirect_access() { When the `crate_type` attribute is used, we no longer need to pass the `--crate-type` flag to `rustc`. -```bash +```shell $ rustc lib.rs $ ls lib* library.rlib diff --git a/src/cargo/test.md b/src/cargo/test.md index b5ace3c6f9..b4bc69d5c5 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -23,13 +23,13 @@ Each file in `tests` is a separate integration test. `cargo` naturally provides an easy way to run all of your tests! -```sh -cargo test +```shell +$ cargo test ``` You should see output like this: -```txt +```shell $ cargo test Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.89 secs @@ -46,11 +46,11 @@ test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out You can also run tests whose name matches a pattern: -```sh -cargo test test_foo +```shell +$ cargo test test_foo ``` -```txt +```shell $ cargo test test_foo Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.35 secs diff --git a/src/crates/lib.md b/src/crates/lib.md index f20fe5990e..92eddc6ac6 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -18,7 +18,7 @@ pub fn indirect_access() { } ``` -```bash +```shell $ rustc --crate-type=lib rary.rs $ ls lib* library.rlib diff --git a/src/crates/link.md b/src/crates/link.md index 6bd17ae988..828fbdbeba 100644 --- a/src/crates/link.md +++ b/src/crates/link.md @@ -19,7 +19,7 @@ fn main() { } ``` -```bash +```txt # Where library.rlib is the path to the compiled library, assumed that it's # in the same directory here: $ rustc executable.rs --extern rary=library.rlib && ./executable diff --git a/src/macros/dry.md b/src/macros/dry.md index a8c06112ca..7333d0e812 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -64,7 +64,7 @@ mod test { } ``` -```bash +```shell $ rustc --test dry.rs && ./dry running 3 tests test test::mul_assign ... ok diff --git a/src/meta/doc.md b/src/meta/doc.md index 2bb34e54ba..4aa2cbf0cc 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -60,7 +60,7 @@ fn main() { To run the tests, first build the code as a library, then tell rustdoc where to find the library so it can link it into each doctest program: -```bash +```shell $ rustc doc.rs --crate-type lib $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` diff --git a/src/mod/split.md b/src/mod/split.md index a7d20aedac..634e7efae1 100644 --- a/src/mod/split.md +++ b/src/mod/split.md @@ -3,7 +3,7 @@ Modules can be mapped to a file/directory hierarchy. Let's break down the [visibility example][visibility] in files: -```bash +```shell $ tree . . |-- my @@ -84,7 +84,7 @@ pub fn public_function() { Let's check that things still work as before: -```bash +```shell $ rustc split.rs && ./split called `my::function()` called `function()` diff --git a/src/scope/raii.md b/src/scope/raii.md index 2b2071707e..7b6bca6184 100644 --- a/src/scope/raii.md +++ b/src/scope/raii.md @@ -41,7 +41,7 @@ fn main() { Of course, we can double check for memory errors using [`valgrind`][valgrind]: -```bash +```shell $ rustc raii.rs && valgrind ./raii ==26873== Memcheck, a memory error detector ==26873== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. diff --git a/src/std/panic.md b/src/std/panic.md index e9005ceb07..b22000494c 100644 --- a/src/std/panic.md +++ b/src/std/panic.md @@ -34,7 +34,7 @@ fn main() { Let's check that `panic!` doesn't leak memory. -```bash +```shell $ rustc panic.rs && valgrind ./panic ==4401== Memcheck, a memory error detector ==4401== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. diff --git a/src/std_misc/arg.md b/src/std_misc/arg.md index 751bf1d98c..b5dd89ce60 100644 --- a/src/std_misc/arg.md +++ b/src/std_misc/arg.md @@ -21,7 +21,7 @@ fn main() { } ``` -```bash +```shell $ ./args 1 2 3 My path is ./args. I got 3 arguments: ["1", "2", "3"]. diff --git a/src/std_misc/arg/matching.md b/src/std_misc/arg/matching.md index 984b05d92f..4cb68eabf0 100644 --- a/src/std_misc/arg/matching.md +++ b/src/std_misc/arg/matching.md @@ -70,7 +70,7 @@ fn main() { } ``` -```bash +```shell $ ./match_args Rust This is not the answer. $ ./match_args 42 diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md index c2dc2ada9a..5fa63d58db 100644 --- a/src/std_misc/file/create.md +++ b/src/std_misc/file/create.md @@ -39,7 +39,7 @@ fn main() { Here's the expected successful output: -```bash +```shell $ mkdir out $ rustc create.rs && ./create successfully wrote to out/lorem_ipsum.txt diff --git a/src/std_misc/file/open.md b/src/std_misc/file/open.md index 2848b076e1..5056197f46 100644 --- a/src/std_misc/file/open.md +++ b/src/std_misc/file/open.md @@ -40,7 +40,7 @@ fn main() { Here's the expected successful output: -```bash +```shell $ echo "Hello World!" > hello.txt $ rustc open.rs && ./open hello.txt contains: diff --git a/src/std_misc/file/read_lines.md b/src/std_misc/file/read_lines.md index 2a2f1855dc..8972227fcb 100644 --- a/src/std_misc/file/read_lines.md +++ b/src/std_misc/file/read_lines.md @@ -33,7 +33,7 @@ where P: AsRef, { ``` Running this program simply prints the lines individually. -```bash +```shell $ echo -e "127.0.0.1\n192.168.0.1\n" > hosts $ rustc read_lines.rs && ./read_lines 127.0.0.1 diff --git a/src/std_misc/fs.md b/src/std_misc/fs.md index 0374c5a205..33612d7b3d 100644 --- a/src/std_misc/fs.md +++ b/src/std_misc/fs.md @@ -100,7 +100,7 @@ fn main() { Here's the expected successful output: -```bash +```shell $ rustc fs.rs && ./fs `mkdir a` `echo hello > a/b.txt` @@ -118,7 +118,7 @@ $ rustc fs.rs && ./fs And the final state of the `a` directory is: -```text +```shell $ tree a a |-- b.txt diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md index b6302a90fb..4c08979e60 100644 --- a/src/testing/dev_dependencies.md +++ b/src/testing/dev_dependencies.md @@ -8,7 +8,7 @@ packages which depend on this package. One such example is using a crate that extends standard `assert!` macros. File `Cargo.toml`: -```ignore +```toml # standard crate data is left out [dev-dependencies] pretty_assertions = "0.4.0" diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index f25ffab285..1896ca556b 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -50,7 +50,7 @@ pub fn div(a: i32, b: i32) -> i32 { Tests can be run with `cargo test`: -```bash +```shell $ cargo test running 0 tests diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index d0e5122b51..2ab0d85a6e 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -30,7 +30,7 @@ fn test_add() { Running tests with `cargo test` command: -```bash +```shell $ cargo test running 0 tests diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index a6060e9c0d..7c401d3e81 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -48,7 +48,7 @@ mod tests { Tests can be run with `cargo test`. -```bash +```shell $ cargo test running 2 tests @@ -112,7 +112,7 @@ mod tests { Running these tests gives us: -```bash +```shell $ cargo test running 3 tests @@ -133,7 +133,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out To run specific tests one may specify the test name to `cargo test` command. -```bash +```shell $ cargo test test_any_panic running 1 test test tests::test_any_panic ... ok @@ -150,7 +150,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out To run multiple tests one may specify part of a test name that matches all the tests that should be run. -```bash +```shell $ cargo test panic running 2 tests test tests::test_any_panic ... ok @@ -198,7 +198,7 @@ mod tests { } ``` -```bash +```shell $ cargo test running 1 test test tests::ignored_test ... ignored From 57f78449fe8ba59152af78091e8c03b8569ecd64 Mon Sep 17 00:00:00 2001 From: Homo Efficio Date: Wed, 17 Jul 2019 01:09:14 +0900 Subject: [PATCH 0941/1122] Add new example for Rc. --- src/SUMMARY.md | 1 + src/std/rc.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/std/rc.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7d91af4307..6121054342 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -175,6 +175,7 @@ - [HashMap](std/hash.md) - [Alternate/custom key types](std/hash/alt_key_types.md) - [HashSet](std/hash/hashset.md) + - [`Rc`](std/rc.md) - [Std misc](std_misc.md) - [Threads](std_misc/threads.md) diff --git a/src/std/rc.md b/src/std/rc.md new file mode 100644 index 0000000000..d89dd9057b --- /dev/null +++ b/src/std/rc.md @@ -0,0 +1,54 @@ +# `Rc` + +When multiple ownership is needed, `Rc`(Reference Counting) can be used. `Rc` keeps track of the number of the references which means the number of owners of the value wrapped inside an `Rc`. + +Reference count of an `Rc` increases by 1 whenever an `Rc` is cloned, and decreases by 1 whenever one cloned `Rc` is dropped out of the scope. When an `Rc`'s reference count becomes zero, which means there are no owners remained, both the `Rc` and the value are all dropped. + +Cloning an `Rc` never do a deep copy. Cloning creates just another pointer to the wrapped value, and increments the count. + +```rust,editable +use std::rc::Rc; + +fn main() { + let rc_examples = "Rc examples".to_string(); + { + println!("--- rc_a is created ---"); + + let rc_a: Rc = Rc::new(rc_examples); + println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a)); + + { + println!("--- rc_a is cloned to rc_b ---"); + + let rc_b: Rc = Rc::clone(&rc_a); + println!("Reference Count of rc_b: {}", Rc::strong_count(&rc_b)); + println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a)); + + // Two `Rc`s are equal if their inner values are equal + println!("rc_a and rc_b are equal: {}", rc_a.eq(&rc_b)); + + // We can use methods of a value directly + println!("Length of the value inside rc_a: {}", rc_a.len()); + println!("Value of rc_b: {}", rc_b); + + println!("--- rc_b is dropped out of scope ---"); + } + + println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a)); + + println!("--- rc_a is dropped out of scope ---"); + } + + // Error! `rc_examples` already moved into `rc_a` + // And when `rc_a` is dropped, `rc_examples` is dropped together + // println!("rc_examples: {}", rc_examples); + // TODO ^ Try uncommenting this line +} +``` + +### See also + +[std::rc][1] and [Arc][2]. + +[1]: https://doc.rust-lang.org/std/rc/index.html +[2]: https://doc.rust-lang.org/std/sync/struct.Arc.html From 0a8dc670e84413871aa191341bf83edb4f909f17 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Thu, 18 Jul 2019 22:52:26 +0300 Subject: [PATCH 0942/1122] maked variable name consistent --- src/error/iter_result.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/error/iter_result.md b/src/error/iter_result.md index 822c9d3828..cef97ae212 100644 --- a/src/error/iter_result.md +++ b/src/error/iter_result.md @@ -5,11 +5,11 @@ An `Iter::map` operation might fail, for example: ```rust,editable fn main() { let strings = vec!["tofu", "93", "18"]; - let possible_numbers: Vec<_> = strings + let numbers: Vec<_> = strings .into_iter() .map(|s| s.parse::()) .collect(); - println!("Results: {:?}", possible_numbers); + println!("Results: {:?}", numbers); } ``` From e39bfaaf4477bb488c1993c66b4b51b5a8407a7b Mon Sep 17 00:00:00 2001 From: funkill2 Date: Fri, 19 Jul 2019 23:20:40 +0300 Subject: [PATCH 0943/1122] reorder links in destructuring.md --- src/flow_control/match/destructuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/match/destructuring.md b/src/flow_control/match/destructuring.md index 9f9a73e025..5e82e6cf54 100644 --- a/src/flow_control/match/destructuring.md +++ b/src/flow_control/match/destructuring.md @@ -2,10 +2,10 @@ A `match` block can destructure items in a variety of ways. +* [Destructuring Tuples][tuple] * [Destructuring Enums][enum] * [Destructuring Pointers][refs] * [Destructuring Structures][struct] -* [Destructuring Tuples][tuple] [enum]: destructuring/destructure_enum.md From 35e3a810a32847febb5267efe79aec8817cd5542 Mon Sep 17 00:00:00 2001 From: David Leung Date: Tue, 23 Jul 2019 16:14:03 +0800 Subject: [PATCH 0944/1122] freeze.md: Incorrect example The freeze example is meant to show that a value cannot be immutably borrowed while the original value is modified within the same scope. However, as the immutably borrowed value is not used after the mutation, the borrow checker allows the example to be compiled successfully, contrary to what we intend to demonstrate. Solution: Use the immutably borrowed value after original value is modified. --- src/scope/borrow/freeze.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scope/borrow/freeze.md b/src/scope/borrow/freeze.md index 29f2d71fb1..b91a1bf01b 100644 --- a/src/scope/borrow/freeze.md +++ b/src/scope/borrow/freeze.md @@ -9,12 +9,14 @@ fn main() { { // Borrow `_mutable_integer` - let _large_integer = &_mutable_integer; + let large_integer = &_mutable_integer; // Error! `_mutable_integer` is frozen in this scope _mutable_integer = 50; // FIXME ^ Comment out this line + println!("Immutably borrowed {}", large_integer); + // `_large_integer` goes out of scope } From 4f968c276a03aa092b911acf942e85aa48768b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9A=D1=80=D0=B0=D0=B2=D1=86=D0=BE=D0=B2?= Date: Thu, 25 Jul 2019 01:49:51 +0300 Subject: [PATCH 0945/1122] Fix typo at error -> panic --- src/error/panic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/panic.md b/src/error/panic.md index 1888d8a78a..a690642539 100644 --- a/src/error/panic.md +++ b/src/error/panic.md @@ -1,7 +1,7 @@ # `panic` The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the task, and usually exits the program. +error message, starts unwinding the stack, and usually exits the program. Here, we explicitly call `panic` on our error condition: ```rust,editable,ignore,mdbook-runnable From 4ce3cc6e403881c49b7d731a0abd5158e6abf41d Mon Sep 17 00:00:00 2001 From: josephrocca <1167575+josephrocca@users.noreply.github.com> Date: Thu, 25 Jul 2019 23:36:20 +1000 Subject: [PATCH 0946/1122] =?UTF-8?q?Snake=20didn't=20deserve=20to=20die?= =?UTF-8?q?=20=F0=9F=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/error/option_unwrap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md index e5760d4e98..6269d5372a 100644 --- a/src/error/option_unwrap.md +++ b/src/error/option_unwrap.md @@ -29,7 +29,7 @@ controlled result while retaining the option to `panic` if desired. fn give_commoner(gift: Option<&str>) { // Specify a course of action for each case. match gift { - Some("snake") => println!("Yuck! I'm throwing that snake in a fire."), + Some("snake") => println!("Yuck! I'm putting this snake back in the forest."), Some(inner) => println!("{}? How nice.", inner), None => println!("No gift? Oh well."), } From 91d7ac8ffa150395eefefb6e5783802670388120 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Sun, 28 Jul 2019 21:39:08 +0300 Subject: [PATCH 0947/1122] maked comments consistent --- src/scope/borrow/alias.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scope/borrow/alias.md b/src/scope/borrow/alias.md index dc26d4c1af..2a12e605f4 100644 --- a/src/scope/borrow/alias.md +++ b/src/scope/borrow/alias.md @@ -19,7 +19,7 @@ fn main() { println!("Point has coordinates: ({}, {}, {})", borrowed_point.x, another_borrow.y, point.z); - // Error! Can't borrow point as mutable because it's currently + // Error! Can't borrow `point` as mutable because it's currently // borrowed as immutable. //let mutable_borrow = &mut point; // TODO ^ Try uncommenting this line @@ -51,9 +51,9 @@ fn main() { // Mutable reference goes out of scope } - // Immutable references to point are allowed again + // Immutable references to `point` are allowed again let borrowed_point = &point; println!("Point now has coordinates: ({}, {}, {})", borrowed_point.x, borrowed_point.y, borrowed_point.z); } -``` \ No newline at end of file +``` From ba73a17199873aadd9b1a68463ea9cd669508dc9 Mon Sep 17 00:00:00 2001 From: David Leung Date: Fri, 2 Aug 2019 15:29:46 +0800 Subject: [PATCH 0948/1122] freeze.md: Fix variable inconsistency in comment --- src/scope/borrow/freeze.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/borrow/freeze.md b/src/scope/borrow/freeze.md index b91a1bf01b..f6dd431b26 100644 --- a/src/scope/borrow/freeze.md +++ b/src/scope/borrow/freeze.md @@ -17,7 +17,7 @@ fn main() { println!("Immutably borrowed {}", large_integer); - // `_large_integer` goes out of scope + // `large_integer` goes out of scope } // Ok! `_mutable_integer` is not frozen in this scope From ee53b5b59acad7c393af4c822a26fa64e58e7327 Mon Sep 17 00:00:00 2001 From: rusty-snake Date: Mon, 5 Aug 2019 18:43:44 +0000 Subject: [PATCH 0949/1122] flow_control/match/binding.md: `...' -> `..=' --- src/flow_control/match/binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index 385035dc15..d3e5d46fdb 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -18,8 +18,8 @@ fn main() { // Could `match` 1 ... 12 directly but then what age // would the child be? Instead, bind to `n` for the // sequence of 1 .. 12. Now the age can be reported. - n @ 1 ... 12 => println!("I'm a child of age {:?}", n), - n @ 13 ... 19 => println!("I'm a teen of age {:?}", n), + n @ 1 ..= 12 => println!("I'm a child of age {:?}", n), + n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n), // Nothing bound. Return the result. n => println!("I'm an old person of age {:?}", n), } From be040518cc9e0843c238788094e222d13799e044 Mon Sep 17 00:00:00 2001 From: rusty-snake Date: Tue, 6 Aug 2019 09:15:30 +0000 Subject: [PATCH 0950/1122] generics/impl.md: follow rustfmt style --- src/generics/impl.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/generics/impl.md b/src/generics/impl.md index 6410739a67..69554316e0 100644 --- a/src/generics/impl.md +++ b/src/generics/impl.md @@ -4,39 +4,43 @@ Similar to functions, implementations require care to remain generic. ```rust struct S; // Concrete type `S` -struct GenericVal(T,); // Generic type `GenericVal` +struct GenericVal(T); // Generic type `GenericVal` // impl of GenericVal where we explicitly specify type parameters: impl GenericVal {} // Specify `f32` impl GenericVal {} // Specify `S` as defined above // `` Must precede the type to remain generic -impl GenericVal {} +impl GenericVal {} ``` ```rust,editable struct Val { - val: f64 + val: f64, } -struct GenVal{ - gen_val: T +struct GenVal { + gen_val: T, } // impl of Val impl Val { - fn value(&self) -> &f64 { &self.val } + fn value(&self) -> &f64 { + &self.val + } } // impl of GenVal for a generic type `T` -impl GenVal { - fn value(&self) -> &T { &self.gen_val } +impl GenVal { + fn value(&self) -> &T { + &self.gen_val + } } fn main() { let x = Val { val: 3.0 }; let y = GenVal { gen_val: 3i32 }; - + println!("{}, {}", x.value(), y.value()); } ``` From 458609f52c311f33981f4ea2ed1bba25f712e090 Mon Sep 17 00:00:00 2001 From: funkill Date: Sun, 4 Aug 2019 21:39:26 +0300 Subject: [PATCH 0951/1122] change read lines chapter title --- src/std_misc/file/read_lines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/std_misc/file/read_lines.md b/src/std_misc/file/read_lines.md index 8972227fcb..6792b1706e 100644 --- a/src/std_misc/file/read_lines.md +++ b/src/std_misc/file/read_lines.md @@ -1,7 +1,7 @@ -# Read Lines +# `read_lines` The method `lines()` returns an iterator over the lines -of a file. +of a file. `File::open` expects a generic, `AsRef`. That's what `read_lines()` expects as input. @@ -18,8 +18,8 @@ fn main() { for line in lines { if let Ok(ip) = line { println!("{}", ip); - } - } + } + } } } From 6707d0be719425e91702fa36dcd5800de57cfbdc Mon Sep 17 00:00:00 2001 From: funkill2 Date: Tue, 6 Aug 2019 18:30:08 +0300 Subject: [PATCH 0952/1122] added space between word and inline code --- src/testing/unit_testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index 7cda2f18fa..22b93435c8 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -167,7 +167,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ## Ignoring tests -Tests can be marked with the`#[ignore]` attribute to exclude some tests. Or to run +Tests can be marked with the `#[ignore]` attribute to exclude some tests. Or to run them with command `cargo test -- --ignored` ```rust From 47428d5c7b1b8c7b00726f90c28006cf2c092890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Romanowski?= Date: Tue, 6 Aug 2019 22:54:39 +0200 Subject: [PATCH 0953/1122] Add destructuring bind examples --- src/flow_control/if_let.md | 5 +++++ src/flow_control/match/binding.md | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index bcdebcedbd..720428d4f1 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -91,6 +91,11 @@ fn main() { if let Foo::Qux(value) = c { println!("c is {}", value); } + + // Binding also works with `if let` + if let Foo::Qux(value @ 100) = c { + println!("c is one hundred"); + } } ``` diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index d3e5d46fdb..e1aa232169 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -26,7 +26,29 @@ fn main() { } ``` +You can also use binding to "destructure" `enum` variants, such as `Option`: + +```rust,editable +fn some_number() -> Option { + Some(42) +} + +fn main() { + match some_number() { + // Got `Some` variant, match if its value, bound to `n`, + // is equal to 42. + Some(n @ 42) => println!("The Answer: {}!", n), + // Match any other number. + Some(n) => println!("Not interesting... {}", n), + // Match anything else (`None` variant). + _ => (), + } +} +``` + ### See also: -[functions] +[`functions`][functions], [`enums`][enums] and [`Option`][option] [functions]: ../../fn.md +[enums]: ../../custom_types/enum.md +[option]: ../../std/option.md From 5be9e49cd4de1f60dd4a1f4924c7d0ea4923175a Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 7 Aug 2019 14:42:19 +0200 Subject: [PATCH 0954/1122] Remove redundant semicolons --- src/flow_control/if_let.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index bcdebcedbd..6b5c200080 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -41,7 +41,7 @@ fn main() { } else { // Destructure failed. Change to the failure case. println!("Didn't match a number. Let's go with a letter!"); - }; + } // Provide an altered failing condition. let i_like_letters = false; @@ -55,7 +55,7 @@ fn main() { } else { // The condition evaluated false. This branch is the default: println!("I don't like letters. Let's go with an emoticon :)!"); - }; + } } ``` From e01ff116bedc9de1d68854f8a96007e2f832b78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= Date: Thu, 8 Aug 2019 11:49:35 +0200 Subject: [PATCH 0955/1122] Change initial parameters in `fibonacci()` call. Fixes #1240 --- src/trait/iter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/iter.md b/src/trait/iter.md index 91f65a53cc..9c9540985b 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -38,7 +38,7 @@ impl Iterator for Fibonacci { // Returns a Fibonacci sequence generator fn fibonacci() -> Fibonacci { - Fibonacci { curr: 1, next: 1 } + Fibonacci { curr: 0, next: 1 } } fn main() { From 6e73335a4c716216ece40470a39e3a5729392009 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Sat, 10 Aug 2019 14:33:21 +0300 Subject: [PATCH 0956/1122] added colon after "See Also" --- src/flow_control/for.md | 2 +- src/hello/print.md | 2 +- src/hello/print/fmt.md | 2 +- src/hello/print/print_debug.md | 2 +- src/hello/print/print_display.md | 2 +- src/hello/print/print_display/testcase_list.md | 2 +- src/std/rc.md | 2 +- src/std_misc/path.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index a8a4762a2d..591b86637c 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -113,7 +113,7 @@ In the above snippets note the type of `match` branch, that is the key difference in the types of iteration. The difference in type then of course implies differing actions that are able to be performed. -### See also +### See also: [Iterator][iter] diff --git a/src/hello/print.md b/src/hello/print.md index 7b1b7ed41e..00b750c8b3 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -80,7 +80,7 @@ Implementing the `fmt::Display` trait automatically implements the check the [`std::fmt`][fmt] documentation for setting the number of decimals to display) -### See also +### See also: [`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], and [`traits`][traits] diff --git a/src/hello/print/fmt.md b/src/hello/print/fmt.md index 5cdcda89f0..dd698d29fc 100644 --- a/src/hello/print/fmt.md +++ b/src/hello/print/fmt.md @@ -82,7 +82,7 @@ Two hints if you get stuck: * You [may need to list each color more than once][named_parameters], * You can [pad with zeros to a width of 2][fmt_width] with `:02`. -### See also +### See also: [`std::fmt`][fmt] diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index 05df667f0d..9f65460768 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -72,7 +72,7 @@ fn main() { One can manually implement `fmt::Display` to control the display. -### See also +### See also: [attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], and [`struct`][structs] diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 55ed8702ad..2083a5f643 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -116,7 +116,7 @@ Display: 3.3 + 7.2i Debug: Complex { real: 3.3, imag: 7.2 } ``` -### See also +### See also: [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index c44c022c62..735b356952 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -66,7 +66,7 @@ Try changing the program so that the index of each element in the vector is also [0: 1, 1: 2, 2: 3] ``` -### See also +### See also: [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], [`?`][q_mark], and [`vec!`][vec] diff --git a/src/std/rc.md b/src/std/rc.md index d89dd9057b..358bd45f39 100644 --- a/src/std/rc.md +++ b/src/std/rc.md @@ -46,7 +46,7 @@ fn main() { } ``` -### See also +### See also: [std::rc][1] and [Arc][2]. diff --git a/src/std_misc/path.md b/src/std_misc/path.md index ae66529c6b..eb83df8e10 100644 --- a/src/std_misc/path.md +++ b/src/std_misc/path.md @@ -38,7 +38,7 @@ fn main() { Be sure to check at other `Path` methods (`posix::Path` or `windows::Path`) and the `Metadata` struct. -### See also +### See also: [OsStr][1] and [Metadata][2]. From e73bb2c5f913fb8201756c47fe518cafb0dbe66c Mon Sep 17 00:00:00 2001 From: Akeem King Date: Sat, 17 Aug 2019 20:18:17 -0400 Subject: [PATCH 0957/1122] Changing Sometime to more appropriate adverb form Sometimes --- src/macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.md b/src/macros.md index ac727f463f..ffeb923e50 100644 --- a/src/macros.md +++ b/src/macros.md @@ -35,6 +35,6 @@ So why are macros useful? 2. Domain-specific languages. Macros allow you to define special syntax for a specific purpose. (More on this later) -3. Variadic interfaces. Sometime you want to define an interface that takes a +3. Variadic interfaces. Sometimes you want to define an interface that takes a variable number of arguments. An example is `println!` which could take any number of arguments, depending on the format string!. (More on this later) From 2d0db07d57e3a93f8c44c604b0a7806bc202d794 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Mon, 2 Sep 2019 23:29:38 +0300 Subject: [PATCH 0958/1122] change russian translation repository --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d4056e90ef..b23b3fc12a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Learn Rust with examples (Live code editor included) ## Using -If you'd like to read Rust by Example, you can visit https://doc.rust-lang.org/rust-by-example/ +If you'd like to read Rust by Example, you can visit https://doc.rust-lang.org/rust-by-example/ to read it online. If you'd like to read it locally, [install Rust], and then: @@ -38,7 +38,7 @@ Please see the [CONTRIBUTING.md] file for more details. * [Chinese](https://github.com/rust-lang-cn/rust-by-example-cn) * [Japanese](https://github.com/rust-lang-ja/rust-by-example-ja) * [French](https://github.com/Songbird0/FR_RBE) -* [Russian](https://github.com/ruRust/rust-by-example-ru) +* [Russian](https://github.com/ruRust/rust-by-example) ## License From 1952353e85acc8e960a43e25e0ebf0306b0b7359 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Thu, 5 Sep 2019 20:22:14 -0500 Subject: [PATCH 0959/1122] Revert "Remove TryFrom due to destabilization" This reverts commit 2a808e6a3d25a26702a4a4a08568904764ae1bea. --- src/SUMMARY.md | 1 + src/conversion/try_from_try_into.md | 45 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/conversion/try_from_try_into.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6121054342..1969ed05a5 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -36,6 +36,7 @@ - [Conversion](conversion.md) - [`From` and `Into`](conversion/from_into.md) + - [`TryFrom` and `TryInto`](conversion/try_from_try_into.md) - [To and from `String`s](conversion/string.md) - [Expressions](expression.md) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md new file mode 100644 index 0000000000..9e3242895b --- /dev/null +++ b/src/conversion/try_from_try_into.md @@ -0,0 +1,45 @@ +# `TryFrom` and `TryInto` + +Similar to [`From` and `Into`][from-into], [`TryFrom`] and [`TryInto`] are +generic traits for converting between types. Unlike `From`/`Into`, the +`TryFrom`/`TryInto` traits are used for fallible conversions, and as such, +return [`Result`]s. + +[from-into]: conversion/from_into.html +[`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html +[`TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html +[`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html + +```rust +use std::convert::TryFrom; +use std::convert::TryInto; + +#[derive(Debug, PartialEq)] +struct EvenNumber(i32); + +impl TryFrom for EvenNumber { + type Error = (); + + fn try_from(value: i32) -> Result { + if value % 2 == 0 { + Ok(EvenNumber(value)) + } else { + Err(()) + } + } +} + +fn main() { + // TryFrom + + assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8))); + assert_eq!(EvenNumber::try_from(5), Err(())); + + // TryInto + + let result: Result = 8i32.try_into(); + assert_eq!(result, Ok(EvenNumber(8))); + let result: Result = 5i32.try_into(); + assert_eq!(result, Err(())); +} +``` From e9464a2c1e1e3ecbee53e063e465b5f5b91e1e58 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Mon, 9 Sep 2019 21:16:01 -0500 Subject: [PATCH 0960/1122] Fix #1110: add examples of ? and Option --- src/SUMMARY.md | 1 + src/error/option_unwrap/question_mark.md | 55 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/error/option_unwrap/question_mark.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1969ed05a5..406d348b9a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -150,6 +150,7 @@ - [Error handling](error.md) - [`panic`](error/panic.md) - [`Option` & `unwrap`](error/option_unwrap.md) + - [Unpacking options with ?](error/option_unwrap/question_mark.md) - [Combinators: `map`](error/option_unwrap/map.md) - [Combinators: `and_then`](error/option_unwrap/and_then.md) - [`Result`](error/result.md) diff --git a/src/error/option_unwrap/question_mark.md b/src/error/option_unwrap/question_mark.md new file mode 100644 index 0000000000..7cff868ad6 --- /dev/null +++ b/src/error/option_unwrap/question_mark.md @@ -0,0 +1,55 @@ +# Unpacking options with ? + +You can unpack Options by using `match` statements, but it's often easier to use the `?` operator. If `x` is an `Option`, then evaluating `x?` will return the underlying value if `x` is Some, otherwise it will terminate whatever function is being executed and return `None`. + +```rust,editable +fn next_birthday(current_age: Option) -> Option { + // If `current_age` is None, this returns None. + // If `current_age` is Some, the inner u8 gets assigned to `next_age` + let next_age: u8 = current_age?; + Some(format!("Next year I will be {}", next_age)) +} +``` + +You can chain many ?s together to make your code much more readable. + +```rust,editable +struct Person { + job: Option, +} + +#[derive(Clone, Copy)] +struct Job { + phone_number: Option, +} + +#[derive(Clone, Copy)] +struct PhoneNumber { + area_code: Option, + number: u32, +} + +impl Person { + + // Gets the area code of the phone number of the person's job, if it exists. + fn work_phone_area_code(&self) -> Option { + // This would need many nested `match` statements without the ? operator. + // It would take a lot more code - try writing it yourself and see which + // is easier. + self.job?.phone_number?.area_code + } +} + +fn main() { + let p = Person { + job: Some(Job { + phone_number: Some(PhoneNumber { + area_code: Some(61), + number: 439222222, + }), + }), + }; + + assert_eq!(p.work_phone_area_code(), Some(61)); +} +``` \ No newline at end of file From 37a2861ccc29af1a939353f3d2d076221b6bdb37 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Mon, 9 Sep 2019 20:13:09 -0500 Subject: [PATCH 0961/1122] Fix #1053: Added a page about the dyn keyword --- src/SUMMARY.md | 1 + src/trait/dyn.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/trait/dyn.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1969ed05a5..8b27814ce4 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -133,6 +133,7 @@ - [Traits](trait.md) - [Derive](trait/derive.md) + - [Returning Traits with `dyn`](trait/dyn.md) - [Operator Overloading](trait/ops.md) - [Drop](trait/drop.md) - [Iterators](trait/iter.md) diff --git a/src/trait/dyn.md b/src/trait/dyn.md new file mode 100644 index 0000000000..5b2f8c2f3e --- /dev/null +++ b/src/trait/dyn.md @@ -0,0 +1,47 @@ +# Returning Traits with `dyn` + +The Rust compiler needs to know how much space every function's return type requires. This means all your functions have to return a concrete type. Unlike other languages, if you have a trait like `Animal`, you can't write a function that returns `Animal`, because its different implementations will need different amounts of memory. + +However, there's an easy workaround. Instead of returning a trait object directly, our functions return a `Box` which _contains_ some `Animal`. A `box` is just a reference to some memory in the heap. Because a reference has a statically-known size, and the compiler can guarantee it points to a heap-allocated `Animal`, we can return a trait from our function! + +Rust tries to be as explicit as possible whenever it allocates memory on the heap. So if your function returns a pointer-to-trait-on-heap in this way, you need to write the return type with the `dyn` keyword, e.g. `Box`. + +```rust,editable +struct Sheep {} +struct Cow {} + +trait Animal { + // Instance method signature + fn noise(&self) -> &'static str; +} + +// Implement the `Animal` trait for `Sheep`. +impl Animal for Sheep { + fn noise(&self) -> &'static str { + "baaaaah!" + } +} + +// Implement the `Animal` trait for `Cow`. +impl Animal for Cow { + fn noise(&self) -> &'static str { + "moooooo!" + } +} + +// Returns some struct that implements Animal, but we don't know which one at compile time. +fn random_animal(random_number: f64) -> Box { + if random_number < 0.5 { + Box::new(Sheep {}) + } else { + Box::new(Cow {}) + } +} + +fn main() { + let random_number = 0.234; + let animal = random_animal(random_number); + println!("You've randomly chosen an animal, and it says {}", animal.noise()); +} + +``` \ No newline at end of file From de659da115e6542d9c00687bf904b44d5125c0f6 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Tue, 10 Sep 2019 17:50:06 -0500 Subject: [PATCH 0962/1122] Fix #1060: document impl Trait on its own page and others --- src/SUMMARY.md | 1 + src/fn/closures/output_parameters.md | 20 +++++------ src/trait/impl_trait.md | 52 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 src/trait/impl_trait.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8b27814ce4..2c55bc38ed 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -137,6 +137,7 @@ - [Operator Overloading](trait/ops.md) - [Drop](trait/drop.md) - [Iterators](trait/iter.md) + - [impl Trait](trait/impl_trait.md) - [Clone](trait/clone.md) - [macro_rules!](macros.md) diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index 0810b281ac..e12e6049ef 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -1,11 +1,9 @@ # As output parameters Closures as input parameters are possible, so returning closures as -output parameters should also be possible. However, returning closure types -are problematic because Rust currently only supports returning concrete -(non-generic) types. Anonymous closure types are, by definition, unknown -and so returning a closure is only possible by making it concrete. This -can be done via boxing. +output parameters should also be possible. However, anonymous +closure types are, by definition, unknown, so we have to use +`impl Trait` to return them. The valid traits for returns are slightly different than before: @@ -21,16 +19,16 @@ dropped as soon as the function exited, leaving invalid references in the closure. ```rust,editable -fn create_fn() -> Box { +fn create_fn() -> impl Fn() { let text = "Fn".to_owned(); - Box::new(move || println!("This is a: {}", text)) + move || println!("This is a: {}", text) } -fn create_fnmut() -> Box { +fn create_fnmut() -> impl FnMut() { let text = "FnMut".to_owned(); - Box::new(move || println!("This is a: {}", text)) + move || println!("This is a: {}", text) } fn main() { @@ -44,10 +42,10 @@ fn main() { ### See also: -[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. +[`Fn`][fn], [`FnMut`][fnmut], [Generics][generics] and [impl Trait][impltrait]. -[box]: ../../std/box.md [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: ../../generics.md +[impltrait]: ../../traits/impl_trait.md diff --git a/src/trait/impl_trait.md b/src/trait/impl_trait.md new file mode 100644 index 0000000000..2ad3795475 --- /dev/null +++ b/src/trait/impl_trait.md @@ -0,0 +1,52 @@ +# impl Trait + +If your function returns a type that implements `MyTrait`, you can write its return type as `-> impl MyTrait`. This can help simplify your type signatures quite a lot! + +```rust,editable +use std::iter; +use std::vec::IntoIter; + +// This function combines two Vec and returns an iterator over it. +// Look how complicated its return type is! +fn combine_vecs_explicit_return_type<'a>( + v: Vec, + u: Vec, +) -> iter::Cycle, IntoIter>> { + v.into_iter().chain(u.into_iter()).cycle() +} + +// This is the exact same function, but its return type uses `impl Trait`. +// Look how much simpler it is! +fn combine_vecs<'a>( + v: Vec, + u: Vec, +) -> impl Iterator { + v.into_iter().chain(u.into_iter()).cycle() +} +``` + +More importantly, some Rust types can't be written out. For example, every closure has its own unnamed concrete type. Before `impl Trait` syntax, you had to allocate on the heap in order to return a closure. But now you can do it all statically, like this: + +```rust,editable +// Returns a function that adds `y` to its input +fn make_adder_function(y: i32) -> impl Fn(i32) -> i32 { + let closure = move |x: i32| { x + y }; + closure +} + +fn main() { + let plus_one = make_adder_function(1); + assert_eq!(plus_one(2), 3); +} +``` + +You can also use `impl Trait` to return an iterator that uses `map` or `filter` closures! This makes using `map` and `filter` easier. Because closure types don't have names, you can't write out an explicit return type if your function returns iterators with closures. But with `impl Trait` you can do this easily: + +```rust,editable +fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a { + numbers + .iter() + .filter(|x| x > &&0) + .map(|x| x * 2) +} +``` \ No newline at end of file From 46474d24c83b3f156a9e2b11e3da8f96d9fad923 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Wed, 11 Sep 2019 14:07:23 -0500 Subject: [PATCH 0963/1122] fix #1067: explain that unit tests can return Result<()> --- src/testing/unit_testing.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index 22b93435c8..a2965d998e 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -70,6 +70,33 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ``` +## Tests and ? +None of the previous unit test examples had a return type. But in Rust 2018, your unit tests can return Result<()>, which lets you use `?` in them! This can make them much more concise. + +```rust,editable +fn sqrt(number: f64) -> Result { + if number >= 0.0 { + Ok(number.powf(0.5)) + } else { + Err("negative floats don't have square roots".to_owned()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sqrt() -> Result<(), String> { + let x = 4.0; + assert_eq!(sqrt(x)?.powf(2.0), x); + Ok(()) + } +} +``` + +See [The Edition Guide][editionguide] for more details. + ## Testing panics To check functions that should panic under certain circumstances, use attribute @@ -230,3 +257,4 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out [panic]: ../std/panic.md [macros]: ../macros.md [mod]: ../mod.md +[editionguide]: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/question-mark-in-main-and-tests.html From 4bfa22726ef25c08a4a340a396aa085ba042968f Mon Sep 17 00:00:00 2001 From: funkill2 Date: Thu, 12 Sep 2019 12:18:41 +0300 Subject: [PATCH 0964/1122] mark some elements as inline code --- src/SUMMARY.md | 2 +- src/error/option_unwrap/question_mark.md | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9ddb31e736..a271438b92 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -152,7 +152,7 @@ - [Error handling](error.md) - [`panic`](error/panic.md) - [`Option` & `unwrap`](error/option_unwrap.md) - - [Unpacking options with ?](error/option_unwrap/question_mark.md) + - [Unpacking options with `?`](error/option_unwrap/question_mark.md) - [Combinators: `map`](error/option_unwrap/map.md) - [Combinators: `and_then`](error/option_unwrap/and_then.md) - [`Result`](error/result.md) diff --git a/src/error/option_unwrap/question_mark.md b/src/error/option_unwrap/question_mark.md index 7cff868ad6..7437ff6c84 100644 --- a/src/error/option_unwrap/question_mark.md +++ b/src/error/option_unwrap/question_mark.md @@ -1,17 +1,20 @@ -# Unpacking options with ? +# Unpacking options with `?` -You can unpack Options by using `match` statements, but it's often easier to use the `?` operator. If `x` is an `Option`, then evaluating `x?` will return the underlying value if `x` is Some, otherwise it will terminate whatever function is being executed and return `None`. +You can unpack `Option`s by using `match` statements, but it's often easier to +use the `?` operator. If `x` is an `Option`, then evaluating `x?` will return +the underlying value if `x` is `Some`, otherwise it will terminate whatever +function is being executed and return `None`. ```rust,editable fn next_birthday(current_age: Option) -> Option { - // If `current_age` is None, this returns None. - // If `current_age` is Some, the inner u8 gets assigned to `next_age` + // If `current_age` is `None`, this returns `None`. + // If `current_age` is `Some`, the inner `u8` gets assigned to `next_age` let next_age: u8 = current_age?; Some(format!("Next year I will be {}", next_age)) } ``` -You can chain many ?s together to make your code much more readable. +You can chain many `?`s together to make your code much more readable. ```rust,editable struct Person { @@ -30,10 +33,10 @@ struct PhoneNumber { } impl Person { - + // Gets the area code of the phone number of the person's job, if it exists. fn work_phone_area_code(&self) -> Option { - // This would need many nested `match` statements without the ? operator. + // This would need many nested `match` statements without the `?` operator. // It would take a lot more code - try writing it yourself and see which // is easier. self.job?.phone_number?.area_code @@ -52,4 +55,4 @@ fn main() { assert_eq!(p.work_phone_area_code(), Some(61)); } -``` \ No newline at end of file +``` From ba3bba823918c5c1183bea848c41ceefc0da0e9f Mon Sep 17 00:00:00 2001 From: funkill2 Date: Thu, 12 Sep 2019 12:40:33 +0300 Subject: [PATCH 0965/1122] added quotes in unit_testing --- src/testing/unit_testing.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/testing/unit_testing.md b/src/testing/unit_testing.md index a2965d998e..cd87706640 100644 --- a/src/testing/unit_testing.md +++ b/src/testing/unit_testing.md @@ -70,8 +70,10 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ``` -## Tests and ? -None of the previous unit test examples had a return type. But in Rust 2018, your unit tests can return Result<()>, which lets you use `?` in them! This can make them much more concise. +## Tests and `?` +None of the previous unit test examples had a return type. But in Rust 2018, +your unit tests can return `Result<()>`, which lets you use `?` in them! This +can make them much more concise. ```rust,editable fn sqrt(number: f64) -> Result { @@ -95,7 +97,7 @@ mod tests { } ``` -See [The Edition Guide][editionguide] for more details. +See ["The Edition Guide"][editionguide] for more details. ## Testing panics From ce28351f7a93d0386dcb1208a128ceb1a9989221 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Thu, 12 Sep 2019 12:42:35 +0300 Subject: [PATCH 0966/1122] added quotes in impl_trait --- src/SUMMARY.md | 2 +- src/trait/impl_trait.md | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a271438b92..f496410d4a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -137,7 +137,7 @@ - [Operator Overloading](trait/ops.md) - [Drop](trait/drop.md) - [Iterators](trait/iter.md) - - [impl Trait](trait/impl_trait.md) + - [`impl Trait`](trait/impl_trait.md) - [Clone](trait/clone.md) - [macro_rules!](macros.md) diff --git a/src/trait/impl_trait.md b/src/trait/impl_trait.md index 2ad3795475..601aaa3b64 100644 --- a/src/trait/impl_trait.md +++ b/src/trait/impl_trait.md @@ -1,12 +1,13 @@ -# impl Trait +# `impl Trait` -If your function returns a type that implements `MyTrait`, you can write its return type as `-> impl MyTrait`. This can help simplify your type signatures quite a lot! +If your function returns a type that implements `MyTrait`, you can write its +return type as `-> impl MyTrait`. This can help simplify your type signatures quite a lot! ```rust,editable use std::iter; use std::vec::IntoIter; -// This function combines two Vec and returns an iterator over it. +// This function combines two `Vec` and returns an iterator over it. // Look how complicated its return type is! fn combine_vecs_explicit_return_type<'a>( v: Vec, @@ -25,7 +26,10 @@ fn combine_vecs<'a>( } ``` -More importantly, some Rust types can't be written out. For example, every closure has its own unnamed concrete type. Before `impl Trait` syntax, you had to allocate on the heap in order to return a closure. But now you can do it all statically, like this: +More importantly, some Rust types can't be written out. For example, every +closure has its own unnamed concrete type. Before `impl Trait` syntax, you had +to allocate on the heap in order to return a closure. But now you can do it all +statically, like this: ```rust,editable // Returns a function that adds `y` to its input @@ -40,7 +44,10 @@ fn main() { } ``` -You can also use `impl Trait` to return an iterator that uses `map` or `filter` closures! This makes using `map` and `filter` easier. Because closure types don't have names, you can't write out an explicit return type if your function returns iterators with closures. But with `impl Trait` you can do this easily: +You can also use `impl Trait` to return an iterator that uses `map` or `filter` +closures! This makes using `map` and `filter` easier. Because closure types don't +have names, you can't write out an explicit return type if your function returns +iterators with closures. But with `impl Trait` you can do this easily: ```rust,editable fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a { @@ -49,4 +56,4 @@ fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a .filter(|x| x > &&0) .map(|x| x * 2) } -``` \ No newline at end of file +``` From d3fe7d152301949e0b6e8db723a7c2dee1a302ac Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Fri, 13 Sep 2019 09:19:58 -0500 Subject: [PATCH 0967/1122] Fix #1253: Document enum type aliases --- src/custom_types/enum.md | 47 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index 5eae819adc..8580ce9f74 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -53,11 +53,56 @@ fn main() { ``` +## Type aliases + +If you use a type alias, you can refer to each enum variant via its alias. +This might be useful if the enum's name is too long or too generic, and you +want to rename it. + +```rust,editable +enum VeryVerboseEnumOfThingsToDoWithNumbers { + Add, + Subtract, +} + +// Creates a type alias +type Operations = VeryVerboseEnumOfThingsToDoWithNumbers; + +fn main() { + // We can refer to each variant via its alias, not its long and inconvenient + // name. + let x = Operations::Add; +} +``` + +The most common place you'll see this is in `impl` blocks using the `Self` alias. + +```rust,editable +enum VeryVerboseEnumOfThingsToDoWithNumbers { + Add, + Subtract, +} + +impl VeryVerboseEnumOfThingsToDoWithNumbers { + fn run(&self, x: i32, y: i32) -> i32 { + match self { + Self::Add => x + y, + Self::Subtract => x - y, + } + } +} +``` + +To learn more about enums and type aliases, you can read the +[stabilization report][aliasreport] from when this feature was stabilized into +Rust. + ### See also: -[`match`][match], [`fn`][fn], and [`String`][str] +[`match`][match], [`fn`][fn], and [`String`][str], [] [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [match]: ../flow_control/match.md [fn]: ../fn.md [str]: ../std/str.md +[aliasreport]: https://github.com/rust-lang/rust/pull/61682/#issuecomment-502472847 From 59dac5d33ddf21eb23ac3689950fb5e31fcc585f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 17 Sep 2019 09:37:37 -0700 Subject: [PATCH 0968/1122] Fix some broken links. --- src/conversion/try_from_try_into.md | 2 +- src/fn/closures/output_parameters.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md index 9e3242895b..230600bf64 100644 --- a/src/conversion/try_from_try_into.md +++ b/src/conversion/try_from_try_into.md @@ -5,7 +5,7 @@ generic traits for converting between types. Unlike `From`/`Into`, the `TryFrom`/`TryInto` traits are used for fallible conversions, and as such, return [`Result`]s. -[from-into]: conversion/from_into.html +[from-into]: from_into.html [`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html [`TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index e12e6049ef..4ac4dd0c4a 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -1,8 +1,8 @@ # As output parameters -Closures as input parameters are possible, so returning closures as -output parameters should also be possible. However, anonymous -closure types are, by definition, unknown, so we have to use +Closures as input parameters are possible, so returning closures as +output parameters should also be possible. However, anonymous +closure types are, by definition, unknown, so we have to use `impl Trait` to return them. The valid traits for returns are slightly different than before: @@ -46,6 +46,6 @@ fn main() { [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html +[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: ../../generics.md -[impltrait]: ../../traits/impl_trait.md +[impltrait]: ../../trait/impl_trait.md From c860ab84e91be959b0439127e06af64c69bae844 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Tue, 17 Sep 2019 22:59:46 -0500 Subject: [PATCH 0969/1122] Fix #90: Extend the traits chapter, add supertraits and Fully Qualified syntax --- src/SUMMARY.md | 2 ++ src/traits/disambiguating.md | 62 ++++++++++++++++++++++++++++++++++++ src/traits/supertraits.md | 43 +++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 src/traits/disambiguating.md create mode 100644 src/traits/supertraits.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index f496410d4a..cd6bbc7b4f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -139,6 +139,8 @@ - [Iterators](trait/iter.md) - [`impl Trait`](trait/impl_trait.md) - [Clone](trait/clone.md) + - [Supertraits](traits/supertraits.md) + - [Disambiguating overlapping traits](traits/disambiguating.md) - [macro_rules!](macros.md) - [Syntax](macros/syntax.md) diff --git a/src/traits/disambiguating.md b/src/traits/disambiguating.md new file mode 100644 index 0000000000..c893e9dc8d --- /dev/null +++ b/src/traits/disambiguating.md @@ -0,0 +1,62 @@ +# Disambiguating overlapping traits + +A type can implement many different traits. What if two traits both require the same name? For example, many traits might have a method named `get()`. They might even have different return types! + +Good news: because each trait implementation gets its own `impl` block, it's +clear which trait's `get` method you're implementing. + +What about when it comes time to _call_ those methods? To disambiguate between +them, we have to use Fully Qualified Syntax. + +```rust,editable +trait UsernameWidget { + // Get the selected username out of this widget + fn get(&self) -> String; +} + +trait AgeWidget { + // Get the selected age out of this widget + fn get(&self) -> u8; +} + +// A form with both a UsernameWidget and an AgeWidget +struct Form { + username: String, + age: u8, +} + +impl UsernameWidget for Form { + fn get(&self) -> String { + self.username.clone() + } +} + +impl AgeWidget for Form { + fn get(&self) -> u8 { + self.age + } +} + +fn main() { + let form = Form{ + username: "rustacean".to_owned(), + age: 28, + }; + + // If you uncomment this line, you'll get an error saying + // "multiple `get` found". Because, after all, there are multiple methods + // named `get`. + // println!("{}", form.get()); + + let username =

::get(&form); + assert_eq!("rustacean".to_owned(), username); + let age = ::get(&form); + assert_eq!(28, age); +} +``` + +### See also: + +[The Rust Programming Language chapter on Fully Qualified syntax][trpl_fqsyntax] + +[trpl_fqsyntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name diff --git a/src/traits/supertraits.md b/src/traits/supertraits.md new file mode 100644 index 0000000000..b28b8f4c9d --- /dev/null +++ b/src/traits/supertraits.md @@ -0,0 +1,43 @@ +# Supertraits + +Rust doesn't have "inheritance", but you can define a trait as being a superset +of another trait. For example: + +```rust,editable +trait Person { + fn name(&self) -> String; +} + +// Student is a supertrait of Person. +// Implementing Student requires you to also impl Person. +trait Student: Person { + fn university(&self) -> String; +} + +trait Programmer { + fn fav_language(&self) -> String; +} + +// CompSciStudent (computer science student) is a supertrait of both Programmer +// and Student. Implementing CompSciStudent requires you to impl both subtraits. +trait CompSciStudent: Programmer + Student { + fn git_username(&self) -> String; +} + +fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String { + format!( + "My name is {} and I attend {}. My Git username is {}", + student.name(), + student.university(), + student.git_username() + ) +} + +fn main() {} +``` + +### See also: + +[The Rust Programming Language chapter on supertraits][trpl_supertraits] + +[trpl_supertraits]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-supertraits-to-require-one-traits-functionality-within-another-trait From 0b7cbcc8afcee40483f9a02b211b600e6143013b Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Wed, 18 Sep 2019 18:15:52 -0500 Subject: [PATCH 0970/1122] Fix #1261: document Iterator::position --- src/SUMMARY.md | 2 +- src/fn/closures/closure_examples/iter_find.md | 39 ++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cd6bbc7b4f..54683d1003 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -69,7 +69,7 @@ - [As output parameters](fn/closures/output_parameters.md) - [Examples in `std`](fn/closures/closure_examples.md) - [Iterator::any](fn/closures/closure_examples/iter_any.md) - - [Iterator::find](fn/closures/closure_examples/iter_find.md) + - [Searching through iterators](fn/closures/closure_examples/iter_find.md) - [Higher Order Functions](fn/hof.md) - [Diverging functions](fn/diverging.md) diff --git a/src/fn/closures/closure_examples/iter_find.md b/src/fn/closures/closure_examples/iter_find.md index 77ddad2ce5..9eb5072e97 100644 --- a/src/fn/closures/closure_examples/iter_find.md +++ b/src/fn/closures/closure_examples/iter_find.md @@ -1,8 +1,8 @@ -# Iterator::find +# Searching through iterators -`Iterator::find` is a function which when passed an iterator, will return -the first element which satisfies the predicate as an `Option`. Its -signature: +`Iterator::find` is a function which iterates over an iterator and searches for the +first value which satisfies some condition. If none of the values satisfy the +condition, it returns `None`. Its signature: ```rust,ignore pub trait Iterator { @@ -29,9 +29,11 @@ fn main() { // `into_iter()` for vecs yields `i32`. let mut into_iter = vec2.into_iter(); - // A reference to what is yielded is `&&i32`. Destructure to `i32`. + // `iter()` for vecs yields `&i32`, and we want to reference one of its + // items, so we have to destructure `&&i32` to `i32` println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2)); - // A reference to what is yielded is `&i32`. Destructure to `i32`. + // `into_iter()` for vecs yields `i32`, and we want to reference one of + // its items, so we have to destructure `&i32` to `i32` println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2)); let array1 = [1, 2, 3]; @@ -44,8 +46,33 @@ fn main() { } ``` +`Iterator::find` gives you a reference to the item. But if you want the _index_ of the +item, use `Iterator::position`. + +```rust,editable +fn main() { + let vec = vec![1, 9, 3, 3, 13, 2]; + + let index_of_first_even_number = vec.iter().position(|x| x % 2 == 0); + assert_eq!(index_of_first_even_number, Some(5)); + + + let index_of_first_negative_number = vec.iter().position(|x| x < &0); + assert_eq!(index_of_first_negative_number, None); +} +``` + ### See also: [`std::iter::Iterator::find`][find] +[`std::iter::Iterator::find_map`][find_map] + +[`std::iter::Iterator::position`][position] + +[`std::iter::Iterator::rposition`][rposition] + [find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find +[find_map]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find_map +[position]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.position +[rposition]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.rposition From 4acc3eb8861bf603965ace6fad5767dec9e78a39 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Thu, 19 Sep 2019 12:30:03 +0300 Subject: [PATCH 0971/1122] move chapters from traits to trait folder --- src/SUMMARY.md | 4 ++-- src/{traits => trait}/disambiguating.md | 0 src/{traits => trait}/supertraits.md | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{traits => trait}/disambiguating.md (100%) rename src/{traits => trait}/supertraits.md (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cd6bbc7b4f..ca5428c103 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -139,8 +139,8 @@ - [Iterators](trait/iter.md) - [`impl Trait`](trait/impl_trait.md) - [Clone](trait/clone.md) - - [Supertraits](traits/supertraits.md) - - [Disambiguating overlapping traits](traits/disambiguating.md) + - [Supertraits](trait/supertraits.md) + - [Disambiguating overlapping traits](trait/disambiguating.md) - [macro_rules!](macros.md) - [Syntax](macros/syntax.md) diff --git a/src/traits/disambiguating.md b/src/trait/disambiguating.md similarity index 100% rename from src/traits/disambiguating.md rename to src/trait/disambiguating.md diff --git a/src/traits/supertraits.md b/src/trait/supertraits.md similarity index 100% rename from src/traits/supertraits.md rename to src/trait/supertraits.md From 60a60b3f220a2d4665578902e8b5e841303e55b3 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Thu, 19 Sep 2019 22:20:08 +0800 Subject: [PATCH 0972/1122] Capturing changes Fixed for NLL --- src/fn/closures/capture.md | 46 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index 36468782f3..dd9127222b 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -18,37 +18,51 @@ fn main() { let color = "green"; - // A closure to print `color` which immediately borrows (`&`) - // `color` and stores the borrow and closure in the `print` - // variable. It will remain borrowed until `print` goes out of - // scope. `println!` only requires `by reference` so it doesn't + // A closure to print `color` which immediately borrows (`&`) `color` and + // stores the borrow and closure in the `print` variable. It will remain + // borrowed until `print` is used the last time. + // + // `println!` only requires arguments by immutable reference so it doesn't // impose anything more restrictive. let print = || println!("`color`: {}", color); // Call the closure using the borrow. print(); + + // `color` can be borrowed immutably again, becuase the closure only holds + // an immutable reference to `color`. + let _reborrow = &color; print(); - let mut count = 0; + // A move or reborrow is allowed after the final use of `print` + let _color_moved = color; - // A closure to increment `count` could take either `&mut count` - // or `count` but `&mut count` is less restrictive so it takes - // that. Immediately borrows `count`. + + let mut count = 0; + // A closure to increment `count` could take either `&mut count` or `count` + // but `&mut count` is less restrictive so it takes that. Immediately + // borrows `count`. // - // A `mut` is required on `inc` because a `&mut` is stored inside. - // Thus, calling the closure mutates the closure which requires - // a `mut`. + // A `mut` is required on `inc` because a `&mut` is stored inside. Thus, + // calling the closure mutates the closure which requires a `mut`. let mut inc = || { count += 1; println!("`count`: {}", count); }; - // Call the closure. - inc(); + // Call the closure using a mutable borrow. inc(); - //let _reborrow = &mut count; + // The closure still mutably borrows an `count` because it is called later. + // An attempt to reborrow will lead to an error. + // let _reborrow = &count; // ^ TODO: try uncommenting this line. + inc(); + + // The closure is no longer in use and no longer needs to borrow `&mut + // count`. Therefore, it is possible to reborrow without an error + let _count_reborrowed = &mut count; + // A non-copy type. let movable = Box::new(3); @@ -64,7 +78,7 @@ fn main() { // `consume` consumes the variable so this can only be called once. consume(); - //consume(); + // consume(); // ^ TODO: Try uncommenting this line. } ``` @@ -82,7 +96,7 @@ fn main() { println!("{}", contains(&1)); println!("{}", contains(&4)); - // `println!("There're {} elements in vec", haystack.len());` + // println!("There're {} elements in vec", haystack.len()); // ^ Uncommenting above line will result in compile-time error // because borrow checker doesn't allow re-using variable after it // has been moved. From a021f4311d858bb3dc58ce039713dbb37df6d8f4 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Thu, 19 Sep 2019 22:26:54 +0800 Subject: [PATCH 0973/1122] typos --- src/fn/closures/capture.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index dd9127222b..007b7a9514 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -53,14 +53,14 @@ fn main() { // Call the closure using a mutable borrow. inc(); - // The closure still mutably borrows an `count` because it is called later. + // The closure still mutably borrows `count` because it is called later. // An attempt to reborrow will lead to an error. // let _reborrow = &count; // ^ TODO: try uncommenting this line. inc(); - // The closure is no longer in use and no longer needs to borrow `&mut - // count`. Therefore, it is possible to reborrow without an error + // The closure no longer needs to borrow `&mut count`. Therefore, it is + // possible to reborrow without an error let _count_reborrowed = &mut count; From eac3fdff77cb0c1290d8ef8354d59a6abe4a309e Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Fri, 20 Sep 2019 07:29:20 +0800 Subject: [PATCH 0974/1122] Typo "because" --- src/fn/closures/capture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index 007b7a9514..d4fa4eadc9 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -29,7 +29,7 @@ fn main() { // Call the closure using the borrow. print(); - // `color` can be borrowed immutably again, becuase the closure only holds + // `color` can be borrowed immutably again, because the closure only holds // an immutable reference to `color`. let _reborrow = &color; print(); From 23df5150dbc89fbb906a200f881cef74aad8c298 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Fri, 20 Sep 2019 20:33:33 +0800 Subject: [PATCH 0975/1122] impl FnOnce() works in 1.35 Update to remove deprecated `FnBox` --- src/fn/closures/output_parameters.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/fn/closures/output_parameters.md b/src/fn/closures/output_parameters.md index 4ac4dd0c4a..6cad1735b9 100644 --- a/src/fn/closures/output_parameters.md +++ b/src/fn/closures/output_parameters.md @@ -5,13 +5,11 @@ output parameters should also be possible. However, anonymous closure types are, by definition, unknown, so we have to use `impl Trait` to return them. -The valid traits for returns are slightly different than before: +The valid traits for returning a closure are: -* `Fn`: normal -* `FnMut`: normal -* `FnOnce`: There are some unusual things at play here, so the [`FnBox`][fnbox] - type is currently needed, and is unstable. This is expected to change in - the future. +* `Fn` +* `FnMut` +* `FnOnce` Beyond this, the `move` keyword must be used, which signals that all captures occur by value. This is required because any captures by reference would be @@ -31,12 +29,20 @@ fn create_fnmut() -> impl FnMut() { move || println!("This is a: {}", text) } +fn create_fnonce() -> impl FnOnce() { + let text = "FnOnce".to_owned(); + + move || println!("This is a: {}", text) +} + fn main() { let fn_plain = create_fn(); let mut fn_mut = create_fnmut(); + let fn_once = create_fnonce(); fn_plain(); fn_mut(); + fn_once(); } ``` @@ -46,6 +52,5 @@ fn main() { [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: ../../generics.md [impltrait]: ../../trait/impl_trait.md From 92420fab6c937d93cc47319afd2995338e71dd58 Mon Sep 17 00:00:00 2001 From: funkill2 Date: Fri, 20 Sep 2019 17:19:38 +0300 Subject: [PATCH 0976/1122] added type alias rfc --- src/custom_types/enum.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/custom_types/enum.md b/src/custom_types/enum.md index 8580ce9f74..e861df9bfd 100644 --- a/src/custom_types/enum.md +++ b/src/custom_types/enum.md @@ -55,7 +55,7 @@ fn main() { ## Type aliases -If you use a type alias, you can refer to each enum variant via its alias. +If you use a type alias, you can refer to each enum variant via its alias. This might be useful if the enum's name is too long or too generic, and you want to rename it. @@ -93,16 +93,17 @@ impl VeryVerboseEnumOfThingsToDoWithNumbers { } ``` -To learn more about enums and type aliases, you can read the +To learn more about enums and type aliases, you can read the [stabilization report][aliasreport] from when this feature was stabilized into -Rust. +Rust. ### See also: -[`match`][match], [`fn`][fn], and [`String`][str], [] +[`match`][match], [`fn`][fn], and [`String`][str], ["Type alias enum variants" RFC][type_alias_rfc] [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [match]: ../flow_control/match.md [fn]: ../fn.md [str]: ../std/str.md [aliasreport]: https://github.com/rust-lang/rust/pull/61682/#issuecomment-502472847 +[type_alias_rfc]: https://rust-lang.github.io/rfcs/2338-type-alias-enum-variants.html From d76368546a9906ad747f4e6b85b82729d6cc7176 Mon Sep 17 00:00:00 2001 From: Andy Gaskell Date: Sun, 22 Sep 2019 17:49:40 -0500 Subject: [PATCH 0977/1122] Make Parsing a String code editable --- src/conversion/string.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conversion/string.md b/src/conversion/string.md index 2bec02f6df..9ced198155 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -38,7 +38,7 @@ trait is implemented for that type. This is implemented for numerous types within the standard library. To obtain this functionality on a user defined type simply implement the [`FromStr`] trait for that type. -```rust +```rust,editable fn main() { let parsed: i32 = "5".parse().unwrap(); let turbo_parsed = "10".parse::().unwrap(); From 2aa835fa829b09571c99ab2cc1bcb9cc8d84f28a Mon Sep 17 00:00:00 2001 From: Andy Gaskell Date: Sun, 22 Sep 2019 19:19:21 -0500 Subject: [PATCH 0978/1122] Fix match range pattern usage --- src/flow_control/match.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/match.md b/src/flow_control/match.md index fb0f56e3d2..02a80670ff 100644 --- a/src/flow_control/match.md +++ b/src/flow_control/match.md @@ -15,7 +15,7 @@ fn main() { // Match several values 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), // Match an inclusive range - 13...19 => println!("A teen"), + 13..=19 => println!("A teen"), // Handle the rest of cases _ => println!("Ain't special"), } @@ -31,4 +31,4 @@ fn main() { println!("{} -> {}", boolean, binary); } -``` \ No newline at end of file +``` From 531c3c24e01b6b416200443bcbf8d68774b70273 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Tue, 24 Sep 2019 19:19:29 +0800 Subject: [PATCH 0979/1122] Reduce rectangle ambiguity changed field names to `top_left` and `bottom_right` --- src/custom_types/structs.md | 25 +++++++++++++++---------- src/std/box.md | 14 ++++++++------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 0b620bf38a..00c4ccd38d 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -29,8 +29,10 @@ struct Point { // Structs can be reused as fields of another struct #[allow(dead_code)] struct Rectangle { - p1: Point, - p2: Point, + // A rectangle can be specified by where the top left and bottom right + // corners are in space. + top_left: Point, + bottom_right: Point, } fn main() { @@ -44,23 +46,26 @@ fn main() { // Instantiate a `Point` - let point: Point = Point { x: 0.3, y: 0.4 }; + let point: Point = Point { x: 10.3, y: 0.4 }; // Access the fields of the point println!("point coordinates: ({}, {})", point.x, point.y); - // Make a new point by using struct update syntax to use the fields of our other one - let new_point = Point { x: 0.1, ..point }; - // `new_point.y` will be the same as `point.y` because we used that field from `point` - println!("second point: ({}, {})", new_point.x, new_point.y); + // Make a new point by using struct update syntax to use the fields of our + // other one + let bottom_right = Point { x: 5.2, ..point }; + + // `bottom_right.y` will be the same as `point.y` because we used that field + // from `point` + println!("second point: ({}, {})", bottom_right.x, bottom_right.y); // Destructure the point using a `let` binding - let Point { x: my_x, y: my_y } = point; + let Point { x: top_edge, y: left_edge } = point; let _rectangle = Rectangle { // struct instantiation is an expression too - p1: Point { x: my_y, y: my_x }, - p2: point, + top_left: Point { x: left_edge, y: top_edge }, + bottom_right: bottom_right, }; // Instantiate a unit struct diff --git a/src/std/box.md b/src/std/box.md index 8d45e1a44e..ebc8ff430a 100644 --- a/src/std/box.md +++ b/src/std/box.md @@ -18,10 +18,12 @@ struct Point { y: f64, } +// A Rectangle can be specified by where its top left and bottom right +// corners are in space #[allow(dead_code)] struct Rectangle { - p1: Point, - p2: Point, + top_left: Point, + bottom_right: Point, } fn origin() -> Point { @@ -38,14 +40,14 @@ fn main() { // Stack allocated variables let point: Point = origin(); let rectangle: Rectangle = Rectangle { - p1: origin(), - p2: Point { x: 3.0, y: 4.0 } + top_left: origin(), + bottom_right: Point { x: 3.0, y: -4.0 } }; // Heap allocated rectangle let boxed_rectangle: Box = Box::new(Rectangle { - p1: origin(), - p2: origin() + top_left: origin(), + bottom_right: Point { x: 3.0, y: -4.0 }, }); // The output of functions can be boxed From cbea4cc92efbf0aa454f35efaafc8551b90f0522 Mon Sep 17 00:00:00 2001 From: illiteratewriter Date: Tue, 1 Oct 2019 02:36:09 +0530 Subject: [PATCH 0980/1122] Add reference to lifetime in structs Lifetimes were not introduced before the struct defenition and therefore caused confusion as to the origin of <'a> --- src/custom_types/structs.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 00c4ccd38d..e863e0ee6b 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -10,6 +10,7 @@ There are three types of structures ("structs") that can be created using the ```rust,editable #[derive(Debug)] struct Person<'a> { + // The 'a defines a lifetime name: &'a str, age: u8, } @@ -54,7 +55,7 @@ fn main() { // Make a new point by using struct update syntax to use the fields of our // other one let bottom_right = Point { x: 5.2, ..point }; - + // `bottom_right.y` will be the same as `point.y` because we used that field // from `point` println!("second point: ({}, {})", bottom_right.x, bottom_right.y); @@ -86,14 +87,15 @@ fn main() { ### Activity -1. Add a function `rect_area` which calculates the area of a rectangle (try - using nested destructuring). +1. Add a function `rect_area` which calculates the area of a rectangle (try + using nested destructuring). 2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`. ### See also: -[`attributes`][attributes] and [destructuring][destructuring] +[`attributes`][attributes], [lifetime][lifetime] and [destructuring][destructuring] [attributes]: ../attribute.md [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [destructuring]: ../flow_control/match/destructuring.md +[lifetime]: ../scope/lifetime.md From d5b61effcb4219c914cbf15e50c894bed6ed7b46 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Sat, 5 Oct 2019 00:29:21 +1000 Subject: [PATCH 0981/1122] Updated aliasing for nll --- src/scope/borrow/alias.md | 71 ++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/scope/borrow/alias.md b/src/scope/borrow/alias.md index 2a12e605f4..59255ed700 100644 --- a/src/scope/borrow/alias.md +++ b/src/scope/borrow/alias.md @@ -1,9 +1,9 @@ # Aliasing Data can be immutably borrowed any number of times, but while immutably -borrowed, the original data can't be mutably borrowed. On the other hand, -only *one* mutable borrow is allowed at a time. The original data can be -borrowed again only *after* the mutable reference goes out of scope. +borrowed, the original data can't be mutably borrowed. On the other hand, only +*one* mutable borrow is allowed at a time. The original data can be borrowed +again only *after* the mutable reference has been used for the last time. ```rust,editable struct Point { x: i32, y: i32, z: i32 } @@ -11,49 +11,50 @@ struct Point { x: i32, y: i32, z: i32 } fn main() { let mut point = Point { x: 0, y: 0, z: 0 }; - { - let borrowed_point = &point; - let another_borrow = &point; + let borrowed_point = &point; + let another_borrow = &point; - // Data can be accessed via the references and the original owner - println!("Point has coordinates: ({}, {}, {})", - borrowed_point.x, another_borrow.y, point.z); + // Data can be accessed via the references and the original owner + println!("Point has coordinates: ({}, {}, {})", + borrowed_point.x, another_borrow.y, point.z); - // Error! Can't borrow `point` as mutable because it's currently - // borrowed as immutable. - //let mutable_borrow = &mut point; - // TODO ^ Try uncommenting this line + // Error! Can't borrow `point` as mutable because it's currently + // borrowed as immutable. + // let mutable_borrow = &mut point; + // TODO ^ Try uncommenting this line - // Immutable references go out of scope - } + // The borrowed values are used again here + println!("Point has coordinates: ({}, {}, {})", + borrowed_point.x, another_borrow.y, point.z); - { - let mutable_borrow = &mut point; + // The immutable references are no longer used for the rest of the code so + // it is possible to reborrow with a mutbale reference. + let mutable_borrow = &mut point; - // Change data via mutable reference - mutable_borrow.x = 5; - mutable_borrow.y = 2; - mutable_borrow.z = 1; + // Change data via mutable reference + mutable_borrow.x = 5; + mutable_borrow.y = 2; + mutable_borrow.z = 1; - // Error! Can't borrow `point` as immutable because it's currently - // borrowed as mutable. - //let y = &point.y; - // TODO ^ Try uncommenting this line + // Error! Can't borrow `point` as immutable because it's currently + // borrowed as mutable. + // let y = &point.y; + // TODO ^ Try uncommenting this line - // Error! Can't print because `println!` takes an immutable reference. - //println!("Point Z coordinate is {}", point.z); - // TODO ^ Try uncommenting this line + // Error! Can't print because `println!` takes an immutable reference. + // println!("Point Z coordinate is {}", point.z); + // TODO ^ Try uncommenting this line - // Ok! Mutable references can be passed as immutable to `println!` - println!("Point has coordinates: ({}, {}, {})", - mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); + // Ok! Mutable references can be passed as immutable to `println!` + println!("Point has coordinates: ({}, {}, {})", + mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); - // Mutable reference goes out of scope - } + // The mutable reference is no longer used for the rest of the code so it + // is possible to reborrow. // Immutable references to `point` are allowed again - let borrowed_point = &point; + let new_borrowed_point = &point; println!("Point now has coordinates: ({}, {}, {})", - borrowed_point.x, borrowed_point.y, borrowed_point.z); + new_borrowed_point.x, new_borrowed_point.y, new_borrowed_point.z); } ``` From 6b8d6aeceac3230899b32f670a6691938bee651a Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Sat, 5 Oct 2019 00:34:54 +1000 Subject: [PATCH 0982/1122] typos --- src/scope/borrow/alias.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scope/borrow/alias.md b/src/scope/borrow/alias.md index 59255ed700..9cfd5fe5dc 100644 --- a/src/scope/borrow/alias.md +++ b/src/scope/borrow/alias.md @@ -28,7 +28,7 @@ fn main() { borrowed_point.x, another_borrow.y, point.z); // The immutable references are no longer used for the rest of the code so - // it is possible to reborrow with a mutbale reference. + // it is possible to reborrow with a mutable reference. let mutable_borrow = &mut point; // Change data via mutable reference @@ -50,9 +50,7 @@ fn main() { mutable_borrow.x, mutable_borrow.y, mutable_borrow.z); // The mutable reference is no longer used for the rest of the code so it - // is possible to reborrow. - - // Immutable references to `point` are allowed again + // is possible to reborrow let new_borrowed_point = &point; println!("Point now has coordinates: ({}, {}, {})", new_borrowed_point.x, new_borrowed_point.y, new_borrowed_point.z); From 6e192269296d58d586d00abbc7733e52292290e8 Mon Sep 17 00:00:00 2001 From: Kishan B Date: Sat, 5 Oct 2019 16:53:48 +0530 Subject: [PATCH 0983/1122] Explicit mention of slice range meaning In `&ys[1 .. 4]` i did not understand whether 4 meant the length or the end index. This is to prevent other readers from having the same confusion. --- src/primitives/array.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/primitives/array.md b/src/primitives/array.md index fe4bee94c2..f612c1dbc2 100644 --- a/src/primitives/array.md +++ b/src/primitives/array.md @@ -42,6 +42,9 @@ fn main() { analyze_slice(&xs); // Slices can point to a section of an array + // They are of the form [starting_index..ending_index] + // starting_index is the first position in the slice + // ending_index is one more than the last position in the slice println!("borrow a section of the array as a slice"); analyze_slice(&ys[1 .. 4]); From b4674bce5b557136eb419ade3b385080ea4bcd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B8=BF=E7=AB=A0?= Date: Thu, 10 Oct 2019 15:10:09 +0800 Subject: [PATCH 0984/1122] `...` range patterns are deprecated --- src/flow_control/match/binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index e1aa232169..0407b37774 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -15,9 +15,9 @@ fn main() { match age() { 0 => println!("I'm not born yet I guess"), - // Could `match` 1 ... 12 directly but then what age + // Could `match` 1 ..= 12 directly but then what age // would the child be? Instead, bind to `n` for the - // sequence of 1 .. 12. Now the age can be reported. + // sequence of 1 ..= 12. Now the age can be reported. n @ 1 ..= 12 => println!("I'm a child of age {:?}", n), n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n), // Nothing bound. Return the result. From 24affdcec037a7544aadae21d4463f06671b9901 Mon Sep 17 00:00:00 2001 From: ngolin Date: Fri, 11 Oct 2019 23:20:13 +0800 Subject: [PATCH 0985/1122] Change misleading `ident` to `expr` If marked as `ident`, `$a.len()` and `$b.len()` are confusing. Actually, `xs` and `ys` are expressions, too. --- src/macros/dry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros/dry.md b/src/macros/dry.md index 7333d0e812..ca015272af 100644 --- a/src/macros/dry.md +++ b/src/macros/dry.md @@ -10,7 +10,7 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for // operators and tokens. - ($a:ident, $b:ident, $func:ident, $op:tt) => { + ($a:expr, $b:expr, $func:ident, $op:tt) => { assert!($a.len() == $b.len(), "{:?}: dimension mismatch: {:?} {:?} {:?}", stringify!($func), From b9b785e71448296784bd98481ffd7ba2d35d93e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B8=BF=E7=AB=A0?= Date: Sat, 12 Oct 2019 14:41:22 +0800 Subject: [PATCH 0986/1122] No `Ok` or `Err`, just `Ok(T)` and `Err(E)` --- src/error/result.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/error/result.md b/src/error/result.md index 3202b314ea..d779bfdad1 100644 --- a/src/error/result.md +++ b/src/error/result.md @@ -5,8 +5,8 @@ describes possible *error* instead of possible *absence*. That is, `Result` could have one of two outcomes: -* `Ok`: An element `T` was found -* `Err`: An error was found with element `E` +* `Ok(T)`: An element `T` was found +* `Err(E)`: An error was found with element `E` By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`. From 0913ff6446d4585b4612fffb304b0644f1c112d5 Mon Sep 17 00:00:00 2001 From: illiteratewriter Date: Sun, 13 Oct 2019 20:06:52 +0530 Subject: [PATCH 0987/1122] Add reference to Generics add links to both Generics and `where` as they have not been used before --- src/fn/closures/input_parameters.md | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/fn/closures/input_parameters.md b/src/fn/closures/input_parameters.md index c97a4d1390..be36c6d361 100644 --- a/src/fn/closures/input_parameters.md +++ b/src/fn/closures/input_parameters.md @@ -1,33 +1,34 @@ # As input parameters -While Rust chooses how to capture variables on the fly mostly without type -annotation, this ambiguity is not allowed when writing functions. When -taking a closure as an input parameter, the closure's complete type must be -annotated using one of a few `traits`. In order of decreasing restriction, +While Rust chooses how to capture variables on the fly mostly without type +annotation, this ambiguity is not allowed when writing functions. When +taking a closure as an input parameter, the closure's complete type must be +annotated using one of a few `traits`. In order of decreasing restriction, they are: * `Fn`: the closure captures by reference (`&T`) * `FnMut`: the closure captures by mutable reference (`&mut T`) * `FnOnce`: the closure captures by value (`T`) -On a variable-by-variable basis, the compiler will capture variables in the -least restrictive manner possible. +On a variable-by-variable basis, the compiler will capture variables in the +least restrictive manner possible. -For instance, consider a parameter annotated as `FnOnce`. This specifies -that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler -will ultimately choose based on how the captured variables are used in the +For instance, consider a parameter annotated as `FnOnce`. This specifies +that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler +will ultimately choose based on how the captured variables are used in the closure. -This is because if a move is possible, then any type of borrow should also -be possible. Note that the reverse is not true. If the parameter is -annotated as `Fn`, then capturing variables by `&mut T` or `T` are not +This is because if a move is possible, then any type of borrow should also +be possible. Note that the reverse is not true. If the parameter is +annotated as `Fn`, then capturing variables by `&mut T` or `T` are not allowed. -In the following example, try swapping the usage of `Fn`, `FnMut`, and +In the following example, try swapping the usage of `Fn`, `FnMut`, and `FnOnce` to see what happens: ```rust,editable // A function which takes a closure as an argument and calls it. +// denotes that F is a "Generic type parameter" fn apply(f: F) where // The closure takes no input and returns nothing. F: FnOnce() { @@ -81,9 +82,11 @@ fn main() { ### See also: -[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce] +[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], [Generics][generics], [where][where] and [`FnOnce`][fnonce] [drop]: https://doc.rust-lang.org/std/mem/fn.drop.html [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html [fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html +[generics]: ../../generics.md +[where]: ../../generics/where.md From b3a901593fb4b19841f7655eb7a3768511f2f36c Mon Sep 17 00:00:00 2001 From: Christian Oeien Date: Sun, 13 Oct 2019 14:24:50 -0500 Subject: [PATCH 0988/1122] Confusing and long sentence --- src/conversion/string.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conversion/string.md b/src/conversion/string.md index 9ced198155..ab1452153a 100644 --- a/src/conversion/string.md +++ b/src/conversion/string.md @@ -29,9 +29,9 @@ fn main() { ## Parsing a String One of the more common types to convert a string into is a number. The idiomatic -approach to this is to use the [`parse`] function and provide the type for the -function to parse the string value into, this can be done either without type -inference or using the 'turbofish' syntax. +approach to this is to use the [`parse`] function and either to arrange for +type inference or to specify the type to parse using the 'turbofish' syntax. +Both alternatives are shown in the following example. This will convert the string into the type specified so long as the [`FromStr`] trait is implemented for that type. This is implemented for numerous types From 8bbf12491b53ba85baf061e246349b570c704b65 Mon Sep 17 00:00:00 2001 From: kaiserd Date: Fri, 18 Oct 2019 11:17:04 +0200 Subject: [PATCH 0989/1122] refactor: simplify extracting Result from Option Using the ?, the code basically extracted an Option from the Result we just built. Just to again wrap it in a Result. We can just return the Result. --- src/error/multiple_error_types/option_result.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/error/multiple_error_types/option_result.md b/src/error/multiple_error_types/option_result.md index 793673f8df..d2273f698f 100644 --- a/src/error/multiple_error_types/option_result.md +++ b/src/error/multiple_error_types/option_result.md @@ -39,9 +39,7 @@ fn double_first(vec: Vec<&str>) -> Result, ParseIntError> { first.parse::().map(|n| 2 * n) }); - let opt = opt.map_or(Ok(None), |r| r.map(Some))?; - - Ok(opt) + opt.map_or(Ok(None), |r| r.map(Some)) } fn main() { From aa63ac6abdd1164e98d25784207a15e4fef4951a Mon Sep 17 00:00:00 2001 From: Marcus Stollsteimer Date: Mon, 28 Oct 2019 09:08:31 +0100 Subject: [PATCH 0990/1122] Fix typos --- src/testing/dev_dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md index 4c08979e60..c20decfa63 100644 --- a/src/testing/dev_dependencies.md +++ b/src/testing/dev_dependencies.md @@ -1,7 +1,7 @@ # Development dependencies -Sometimes there is a need to have a dependencies for tests (examples, -benchmarks) only. Such dependencies are added to `Cargo.toml` in +Sometimes there is a need to have dependencies for tests (examples, +benchmarks) only. Such dependencies are added to `Cargo.toml` in the `[dev-dependencies]` section. These dependencies are not propagated to other packages which depend on this package. From 11b26c87cfafafc922c48577a94b449dfd4f406b Mon Sep 17 00:00:00 2001 From: Marcus Stollsteimer Date: Mon, 28 Oct 2019 09:11:04 +0100 Subject: [PATCH 0991/1122] Improve Cargo / Dependencies section --- src/cargo/deps.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 21db4c2a65..7403a2ae76 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -15,10 +15,10 @@ cargo new foo cargo new --lib foo ``` -For the rest of this chapter, I will assume we are making a binary, rather than +For the rest of this chapter, let's assume we are making a binary, rather than a library, but all of the concepts are the same. -After the above commands, you should see something like this: +After the above commands, you should see a file hierarchy like this: ```txt foo @@ -40,7 +40,7 @@ authors = ["mark"] [dependencies] ``` -The `name` field under `package` determines the name of the project. This is +The `name` field under `[package]` determines the name of the project. This is used by `crates.io` if you publish the crate (more later). It is also the name of the output binary when you compile. @@ -49,14 +49,14 @@ Versioning](http://semver.org/). The `authors` field is a list of authors used when publishing the crate. -The `dependencies` section lets you add a dependency for your project. +The `[dependencies]` section lets you add dependencies for your project. -For example, suppose that I want my program to have a great CLI. You can find +For example, suppose that we want our program to have a great CLI. You can find lots of great packages on [crates.io](https://crates.io) (the official Rust package registry). One popular choice is [clap](https://crates.io/crates/clap). As of this writing, the most recent published version of `clap` is `2.27.1`. To add a dependency to our program, we can simply add the following to our -`Cargo.toml` under `dependencies`: `clap = "2.27.1"`. And of course, `extern +`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`. And of course, `extern crate clap` in `main.rs`, just like normal. And that's it! You can start using `clap` in your program. From 3af0217a5362974cfa016bf14550fc761f7b518b Mon Sep 17 00:00:00 2001 From: Marcus Stollsteimer Date: Mon, 28 Oct 2019 09:11:31 +0100 Subject: [PATCH 0992/1122] Improve Cargo / Build Scripts section --- src/cargo/build_scripts.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cargo/build_scripts.md b/src/cargo/build_scripts.md index c5da00db6a..6db3afe90a 100644 --- a/src/cargo/build_scripts.md +++ b/src/cargo/build_scripts.md @@ -1,7 +1,7 @@ # Build Scripts -Sometimes a normal build from cargo is not enough. Perhaps your crate needs some -pre-requisites before cargo will successfully compile, things like code +Sometimes a normal build from `cargo` is not enough. Perhaps your crate needs +some pre-requisites before `cargo` will successfully compile, things like code generation, or some native code that needs to be compiled. To solve this problem we have build scripts that Cargo can run. @@ -20,7 +20,7 @@ default. ## How to use a build script The build script is simply another Rust file that will be compiled and invoked -prior to compiling anything else in the package. Hence it can be used to fulfil +prior to compiling anything else in the package. Hence it can be used to fulfill pre-requisites of your crate. Cargo provides the script with inputs via environment variables [specified @@ -29,10 +29,11 @@ here] that can be used. The script provides output via stdout. All lines printed are written to `target/debug/build//output`. Further, lines prefixed with `cargo:` will be interpreted by Cargo directly and hence can be used to define parameters for the -packages compilation. +package's compilation. -For further specification and examples have a read of the [cargo specification]. +For further specification and examples have a read of the +[Cargo specification][cargo_specification]. [specified here]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts -[cargo specification]: https://doc.rust-lang.org/cargo/reference/build-scripts.html \ No newline at end of file +[cargo_specification]: https://doc.rust-lang.org/cargo/reference/build-scripts.html From e5d71fbe80f2262ad4341737763d44e0d2ef2390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20Csord=C3=A1s?= Date: Mon, 28 Oct 2019 13:48:20 +0100 Subject: [PATCH 0993/1122] Make if_let exercise runnable --- src/flow_control/if_let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index a5671332b9..22bdde8d1b 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -103,7 +103,7 @@ Another benefit: `if let` allows to match enum non-parameterized variants, even Would you like a challenge? Fix the following example to use `if let`: -```rust,editable,ignore +```rust,editable,ignore,mdbook-runnable // This enum purposely doesn't #[derive(PartialEq)], // neither we implement PartialEq for it. That's why comparing Foo::Bar==a fails below. enum Foo {Bar} From eaf891dfdabc824deda825ff068ea3cbf2c4afd8 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 9 Nov 2019 03:14:53 +0000 Subject: [PATCH 0994/1122] Enable section-folding of table of content The section-folding configuration has landed in mdBook. Enable this would make sidebar a little bit clear. --- book.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/book.toml b/book.toml index 60770d4eee..45ae5fd944 100644 --- a/book.toml +++ b/book.toml @@ -6,3 +6,6 @@ author = "The Rust Community" [output.html.playpen] editable = true editor = "ace" + +[output.html.fold] +enable = true From fba7a49dad057e75a9dc0fa94dec913543f955d9 Mon Sep 17 00:00:00 2001 From: Jean Vintache Date: Wed, 13 Nov 2019 23:51:23 +0100 Subject: [PATCH 0995/1122] crates: fix suggested value for --crate-type flag In order to compile to a library, suggest using `lib` instead of `rustc`, which is not a valid `--crate-type` value. --- src/crates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crates.md b/src/crates.md index 4c46e553cd..b954eec6cd 100644 --- a/src/crates.md +++ b/src/crates.md @@ -9,4 +9,4 @@ individually, only crates get compiled. A crate can be compiled into a binary or into a library. By default, `rustc` will produce a binary from a crate. This behavior can be overridden by passing -the `--crate-type` flag to `rustc`. +the `--crate-type` flag to `lib`. From 4fa4eb0d283127d969e3de01c91203c4970e1e92 Mon Sep 17 00:00:00 2001 From: Rob Starling Date: Sat, 30 Nov 2019 18:19:03 -0800 Subject: [PATCH 0996/1122] Make TryFrom & TryInto example editable --- src/conversion/try_from_try_into.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conversion/try_from_try_into.md b/src/conversion/try_from_try_into.md index 230600bf64..ac62ad154b 100644 --- a/src/conversion/try_from_try_into.md +++ b/src/conversion/try_from_try_into.md @@ -10,7 +10,7 @@ return [`Result`]s. [`TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html -```rust +```rust,editable use std::convert::TryFrom; use std::convert::TryInto; From dcf37b6879cb64c27771edbbca5d3a143e791675 Mon Sep 17 00:00:00 2001 From: Jingjing Duan Date: Fri, 20 Dec 2019 21:51:22 -1000 Subject: [PATCH 0997/1122] Remove unnecessary lifetime annotation --- src/trait/impl_trait.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/trait/impl_trait.md b/src/trait/impl_trait.md index 601aaa3b64..7b87bd2e9c 100644 --- a/src/trait/impl_trait.md +++ b/src/trait/impl_trait.md @@ -9,7 +9,7 @@ use std::vec::IntoIter; // This function combines two `Vec` and returns an iterator over it. // Look how complicated its return type is! -fn combine_vecs_explicit_return_type<'a>( +fn combine_vecs_explicit_return_type( v: Vec, u: Vec, ) -> iter::Cycle, IntoIter>> { @@ -18,12 +18,24 @@ fn combine_vecs_explicit_return_type<'a>( // This is the exact same function, but its return type uses `impl Trait`. // Look how much simpler it is! -fn combine_vecs<'a>( +fn combine_vecs( v: Vec, u: Vec, ) -> impl Iterator { v.into_iter().chain(u.into_iter()).cycle() } + +fn main() { + let v1 = vec![1, 2, 3]; + let v2 = vec![4, 5]; + let mut v3 = combine_vecs(v1, v2); + assert_eq!(Some(1), v3.next()); + assert_eq!(Some(2), v3.next()); + assert_eq!(Some(3), v3.next()); + assert_eq!(Some(4), v3.next()); + assert_eq!(Some(5), v3.next()); + println!("all done"); +} ``` More importantly, some Rust types can't be written out. For example, every From c4dff961f0655d6ee3fffb29631433dc804f9eaa Mon Sep 17 00:00:00 2001 From: Adamas Date: Fri, 27 Dec 2019 10:00:01 +0800 Subject: [PATCH 0998/1122] eliminate the warnings if there is no `dyn`, there are warnings like this: warning: trait objects without an explicit `dyn` are deprecated --> xxx.rs:5:45 | 5 | type Result = std::result::Result>; | ^^^^^^^^^^^^ help: use `dyn`: `dyn error::Error` | = note: `#[warn(bare_trait_objects)]` on by default warning: trait objects without an explicit `dyn` are deprecated --> xxx.rs:21:32 | 21 | fn cause(&self) -> Option<&error::Error> { | ^^^^^^^^^^^^ help: use `dyn`: `dyn error::Error` --- src/error/multiple_error_types/boxing_errors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index e2eb68607e..b0fc2aa3ec 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -13,7 +13,7 @@ use std::error; use std::fmt; // Change the alias to `Box`. -type Result = std::result::Result>; +type Result = std::result::Result>; #[derive(Debug, Clone)] struct EmptyVec; @@ -29,7 +29,7 @@ impl error::Error for EmptyVec { "invalid first item to double" } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&(dyn error::Error)> { // Generic error, underlying cause isn't tracked. None } From 2d39e2894830331fb02b77980a6190e972ad3d68 Mon Sep 17 00:00:00 2001 From: Cawibo Date: Thu, 9 Jan 2020 23:40:26 +0100 Subject: [PATCH 0999/1122] CamelCase -> UpperCamelCase The compiler will raise a warning unless it is UpperCamelCase. Since the warning is explicit about mentioning "upper", maybe the guide should too? --- src/types/alias.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/alias.md b/src/types/alias.md index c839f53213..5fda9477e8 100644 --- a/src/types/alias.md +++ b/src/types/alias.md @@ -1,7 +1,7 @@ # Aliasing The `type` statement can be used to give a new name to an existing type. Types -must have `CamelCase` names, or the compiler will raise a warning. The +must have `UpperCamelCase` names, or the compiler will raise a warning. The exception to this rule are the primitive types: `usize`, `f32`, etc. ```rust,editable @@ -33,4 +33,4 @@ is an alias for the `Result` type. ### See also: -[Attributes](../attribute.md) \ No newline at end of file +[Attributes](../attribute.md) From d370e7771fca8c95a9278abb8c5b80f513acc90f Mon Sep 17 00:00:00 2001 From: Matthew Healy Date: Mon, 3 Feb 2020 10:29:03 +0100 Subject: [PATCH 1000/1122] Tighten grammar of 'for and iterators' section --- src/flow_control/for.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 591b86637c..99e6458493 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -49,14 +49,13 @@ fn main() { ## for and iterators The `for in` construct is able to interact with an `Iterator` in several ways. -As discussed in with the [Iterator][iter] trait, if not specified, the `for` -loop will apply the `into_iter` function on the collection provided to convert -the collection into an iterator. This is not the only means to convert a -collection into an iterator however, the other functions available include -`iter` and `iter_mut`. - -These 3 functions will return different views of the data within your -collection. +As discussed in the section on the [Iterator][iter] trait, by default the `for` +loop will apply the `into_iter` function to the collection. However, this is +not the only means of converting collections into iterators. + +`into_iter`, `iter` and `iter_mut` all handle the conversion of a collection +into an iterator in different ways, by providing different views on the data +within. * `iter` - This borrows each element of the collection through each iteration. Thus leaving the collection untouched and available for reuse after the loop. From 9d1113503e242cee00cdfd34fe6193faf13190af Mon Sep 17 00:00:00 2001 From: Matthew Healy Date: Mon, 3 Feb 2020 10:33:15 +0100 Subject: [PATCH 1001/1122] Tighten grammar in 'if let' section --- src/flow_control/if_let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 22bdde8d1b..953e82fd8d 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -99,7 +99,7 @@ fn main() { } ``` -Another benefit: `if let` allows to match enum non-parameterized variants, even if the enum doesn't `#[derive(PartialEq)]`, neither we implement `PartialEq` for it. In such case, classic `if Foo::Bar==a` fails, because instances of such enum are not comparable for equality. However, `if let` works. +Another benefit is that `if let` allows us to match non-parameterized enum variants. This is true even in cases where the enum doesn't implement or derive `PartialEq`. In such cases `if Foo::Bar == a` would fail to compile, because instances of the enum cannot be equated, however `if let` will continue to work. Would you like a challenge? Fix the following example to use `if let`: From 80e7efb1b72317bd2caf009f9c83e6035157ba7f Mon Sep 17 00:00:00 2001 From: Patricio Palladino Date: Mon, 10 Feb 2020 19:45:35 -0300 Subject: [PATCH 1002/1122] Add missing `dyn` --- src/error/multiple_error_types/reenter_question_mark.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index bf93e8a42d..a94c0f8e5e 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -26,8 +26,8 @@ Here, we rewrite the previous example using `?`. As a result, the use std::error; use std::fmt; -// Change the alias to `Box`. -type Result = std::result::Result>; +// Change the alias to `Box`. +type Result = std::result::Result>; #[derive(Debug)] struct EmptyVec; From 3e2bd2aa042c2bd916b66670cadf184deabdbb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Lesin=CC=81ski?= Date: Mon, 17 Feb 2020 15:32:59 +0000 Subject: [PATCH 1003/1122] Don't suggest Into implements a reverse conversion --- src/conversion/from_into.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conversion/from_into.md b/src/conversion/from_into.md index 9be8bc24ad..266d10f285 100644 --- a/src/conversion/from_into.md +++ b/src/conversion/from_into.md @@ -43,8 +43,8 @@ fn main() { ## `Into` The [`Into`] trait is simply the reciprocal of the `From` trait. That is, if you -have implemented the `From` trait for your type you get the `Into` -implementation for free. +have implemented the `From` trait for your type, `Into` will call it when +necessary. Using the `Into` trait will typically require specification of the type to convert into as the compiler is unable to determine this most of the time. From fca945a3efde1b59372fdd87aeadec01833e5496 Mon Sep 17 00:00:00 2001 From: Michael Morehouse <640167+yawpitch@users.noreply.github.com> Date: Tue, 18 Feb 2020 12:41:45 +0000 Subject: [PATCH 1004/1122] Improve grammar in example of 'in let' section Extends work done in #1305 to comments in the example code. --- src/flow_control/if_let.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 953e82fd8d..708ecfd59b 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -104,8 +104,8 @@ Another benefit is that `if let` allows us to match non-parameterized enum varia Would you like a challenge? Fix the following example to use `if let`: ```rust,editable,ignore,mdbook-runnable -// This enum purposely doesn't #[derive(PartialEq)], -// neither we implement PartialEq for it. That's why comparing Foo::Bar==a fails below. +// This enum purposely neither implements nor derives PartialEq). +// That is why comparing Foo::Bar == a fails below. enum Foo {Bar} fn main() { From b461a3a561ec76bee75f67893b4615a9bcf64387 Mon Sep 17 00:00:00 2001 From: Michael Morehouse <640167+yawpitch@users.noreply.github.com> Date: Tue, 18 Feb 2020 16:25:08 +0000 Subject: [PATCH 1005/1122] Fixes errant parenthesis --- src/flow_control/if_let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/if_let.md b/src/flow_control/if_let.md index 708ecfd59b..3742b6f683 100644 --- a/src/flow_control/if_let.md +++ b/src/flow_control/if_let.md @@ -104,7 +104,7 @@ Another benefit is that `if let` allows us to match non-parameterized enum varia Would you like a challenge? Fix the following example to use `if let`: ```rust,editable,ignore,mdbook-runnable -// This enum purposely neither implements nor derives PartialEq). +// This enum purposely neither implements nor derives PartialEq. // That is why comparing Foo::Bar == a fails below. enum Foo {Bar} From cd30ea3f42ae45f28b2d96827b55b8c8ff706252 Mon Sep 17 00:00:00 2001 From: Michael Morehouse <640167+yawpitch@users.noreply.github.com> Date: Tue, 18 Feb 2020 19:28:12 +0000 Subject: [PATCH 1006/1122] Minor typo fix in src/mod/visibility Believe this was meant to read "mod" not "mode", but "module" seems clearest. --- src/mod/visibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/visibility.md b/src/mod/visibility.md index 84840e43de..173122c72a 100644 --- a/src/mod/visibility.md +++ b/src/mod/visibility.md @@ -101,7 +101,7 @@ fn main() { // pub(crate) items can be called from anywhere in the same crate my_mod::public_function_in_crate(); - // pub(in path) items can only be called from within the mode specified + // pub(in path) items can only be called from within the module specified // Error! function `public_function_in_my_mod` is private //my_mod::nested::public_function_in_my_mod(); // TODO ^ Try uncommenting this line From c657311f016af5a8a91f839c8cedac4b62ffbfb0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 21 Feb 2020 09:26:04 -0800 Subject: [PATCH 1007/1122] Use rust-lang/rust linkchecker on CI. --- .travis.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ec2b34850..b686a2f5d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ sudo: false language: rust -cache: cargo rust: - nightly branches: @@ -8,15 +7,17 @@ branches: - master before_script: - | - LATEST=$(cargo search mdbook | grep "^mdbook =" | cut -d '"' -f 2) - INSTALLED=$(cargo install --list | grep "^mdbook " | cut -d v -f 2 | tr -d :) - if [ "$INSTALLED" != "$LATEST" ]; then - if [ "$INSTALLED" != "" ]; then - echo "mdbook '$INSTALLED' is already installed" - fi - echo "Installing mdbook '$LATEST'" - cargo install mdbook --force --vers "$LATEST" - fi + set -ex + rustup --version + rustc -Vv + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.5/mdbook-v0.3.5-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin + mdbook --version + rustup toolchain update nightly -c rust-docs script: - mdbook build - mdbook test + - | + set -e + curl -sSLo linkcheck.sh \ + https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh + sh linkcheck.sh --all rust-by-example From 6bd86d4549fccdfde2bf31e6566a02033e606732 Mon Sep 17 00:00:00 2001 From: Max Hausch Date: Sun, 8 Mar 2020 23:09:32 +0100 Subject: [PATCH 1008/1122] Clarify type suffixing with example I did not understand this principle the first time i read it. I tried `31 i64`, `31: i64` until i saw an example in the primitives chapter. --- src/hello/print.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hello/print.md b/src/hello/print.md index 00b750c8b3..6efa8eb711 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -9,7 +9,7 @@ some of which include: * `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr). * `eprintln!`: same as `eprint!`but a newline is appended. -All parse text in the same fashion. As a plus, Rust checks formatting +All parse text in the same fashion. As a plus, Rust checks formatting correctness at compile time. ```rust,editable,ignore,mdbook-runnable @@ -19,7 +19,7 @@ fn main() { println!("{} days", 31); // Without a suffix, 31 becomes an i32. You can change what type 31 is - // by providing a suffix. + // by providing a suffix. The number 31i64 for example has the type i64. // There are various optional patterns this works with. Positional // arguments can be used. From cb32f06c81e4d31d1bc27e05ca52a64bfe57378b Mon Sep 17 00:00:00 2001 From: dalance Date: Wed, 11 Mar 2020 19:43:14 +0900 Subject: [PATCH 1009/1122] Rewrite freeze.md --- src/SUMMARY.md | 2 +- src/{scope/borrow => variable_bindings}/freeze.md | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) rename src/{scope/borrow => variable_bindings}/freeze.md (50%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 85711fff22..3e3e0aa319 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -27,6 +27,7 @@ - [Mutability](variable_bindings/mut.md) - [Scope and Shadowing](variable_bindings/scope.md) - [Declare first](variable_bindings/declare.md) + - [Freezing](variable_bindings/freeze.md) - [Types](types.md) - [Casting](types/cast.md) @@ -117,7 +118,6 @@ - [Mutability](scope/move/mut.md) - [Borrowing](scope/borrow.md) - [Mutability](scope/borrow/mut.md) - - [Freezing](scope/borrow/freeze.md) - [Aliasing](scope/borrow/alias.md) - [The ref pattern](scope/borrow/ref.md) - [Lifetimes](scope/lifetime.md) diff --git a/src/scope/borrow/freeze.md b/src/variable_bindings/freeze.md similarity index 50% rename from src/scope/borrow/freeze.md rename to src/variable_bindings/freeze.md index f6dd431b26..b399570ff8 100644 --- a/src/scope/borrow/freeze.md +++ b/src/variable_bindings/freeze.md @@ -1,23 +1,21 @@ # Freezing -When data is immutably borrowed, it also *freezes*. *Frozen* data can't be -modified via the original object until all references to it go out of scope: +When data is bound by the same name immutably, it also *freezes*. *Frozen* data can't be +modified until the immutable binding goes out of scope: ```rust,editable,ignore,mdbook-runnable fn main() { let mut _mutable_integer = 7i32; { - // Borrow `_mutable_integer` - let large_integer = &_mutable_integer; + // Shadowing by immutable `_mutable_integer` + let _mutable_integer = _mutable_integer; // Error! `_mutable_integer` is frozen in this scope _mutable_integer = 50; // FIXME ^ Comment out this line - println!("Immutably borrowed {}", large_integer); - - // `large_integer` goes out of scope + // `_mutable_integer` goes out of scope } // Ok! `_mutable_integer` is not frozen in this scope From 3380d843d0cb6822b68125ba46ee03886595eecb Mon Sep 17 00:00:00 2001 From: Sebastian Magnusson Date: Tue, 17 Mar 2020 09:59:36 +0100 Subject: [PATCH 1010/1122] Remove mdbook version flags from README The instructions in README.md are now more similar to those in CONTRIBUTING.md. Following these instructions seems to work as intended. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b23b3fc12a..a2ac7c65ce 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you'd like to read it locally, [install Rust], and then: ```bash $ git clone https://github.com/rust-lang/rust-by-example $ cd rust-by-example -$ cargo install mdbook --version 0.2 --force +$ cargo install mdbook $ mdbook build $ mdbook serve ``` From afa9d6c46c96058fe644ba84b01d15426057d2c8 Mon Sep 17 00:00:00 2001 From: olehmisar Date: Sun, 22 Mar 2020 19:30:24 +0200 Subject: [PATCH 1011/1122] Remove deprecated `std::error::Error::description` --- src/error/multiple_error_types/boxing_errors.md | 11 +---------- .../multiple_error_types/reenter_question_mark.md | 11 +---------- src/std_misc/file/create.md | 12 +++++------- src/std_misc/file/open.md | 10 ++-------- src/std_misc/process/pipe.md | 9 +++------ 5 files changed, 12 insertions(+), 41 deletions(-) diff --git a/src/error/multiple_error_types/boxing_errors.md b/src/error/multiple_error_types/boxing_errors.md index b0fc2aa3ec..84b0c41e55 100644 --- a/src/error/multiple_error_types/boxing_errors.md +++ b/src/error/multiple_error_types/boxing_errors.md @@ -24,16 +24,7 @@ impl fmt::Display for EmptyVec { } } -impl error::Error for EmptyVec { - fn description(&self) -> &str { - "invalid first item to double" - } - - fn cause(&self) -> Option<&(dyn error::Error)> { - // Generic error, underlying cause isn't tracked. - None - } -} +impl error::Error for EmptyVec {} fn double_first(vec: Vec<&str>) -> Result { vec.first() diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index a94c0f8e5e..61f80fc3e3 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -38,16 +38,7 @@ impl fmt::Display for EmptyVec { } } -impl error::Error for EmptyVec { - fn description(&self) -> &str { - "invalid first item to double" - } - - fn cause(&self) -> Option<&error::Error> { - // Generic error, underlying cause isn't tracked. - None - } -} +impl error::Error for EmptyVec {} // The same structure as before but rather than chain all `Results` // and `Options` along, we `?` to get the inner value out immediately. diff --git a/src/std_misc/file/create.md b/src/std_misc/file/create.md index 5fa63d58db..16eba89747 100644 --- a/src/std_misc/file/create.md +++ b/src/std_misc/file/create.md @@ -14,24 +14,23 @@ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "; -use std::error::Error; use std::fs::File; use std::io::prelude::*; use std::path::Path; fn main() { - let path = Path::new("out/lorem_ipsum.txt"); + let path = Path::new("lorem_ipsum.txt"); let display = path.display(); // Open a file in write-only mode, returns `io::Result` let mut file = match File::create(&path) { - Err(why) => panic!("couldn't create {}: {}", display, why.description()), + Err(why) => panic!("couldn't create {}: {}", display, why), Ok(file) => file, }; // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>` match file.write_all(LOREM_IPSUM.as_bytes()) { - Err(why) => panic!("couldn't write to {}: {}", display, why.description()), + Err(why) => panic!("couldn't write to {}: {}", display, why), Ok(_) => println!("successfully wrote to {}", display), } } @@ -40,10 +39,9 @@ fn main() { Here's the expected successful output: ```shell -$ mkdir out $ rustc create.rs && ./create -successfully wrote to out/lorem_ipsum.txt -$ cat out/lorem_ipsum.txt +successfully wrote to lorem_ipsum.txt +$ cat lorem_ipsum.txt Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo diff --git a/src/std_misc/file/open.md b/src/std_misc/file/open.md index 5056197f46..16fdb2c91c 100644 --- a/src/std_misc/file/open.md +++ b/src/std_misc/file/open.md @@ -6,7 +6,6 @@ A `File` owns a resource, the file descriptor and takes care of closing the file when it is `drop`ed. ```rust,editable,ignore -use std::error::Error; use std::fs::File; use std::io::prelude::*; use std::path::Path; @@ -18,24 +17,19 @@ fn main() { // Open the path in read-only mode, returns `io::Result` let mut file = match File::open(&path) { - // The `description` method of `io::Error` returns a string that - // describes the error - Err(why) => panic!("couldn't open {}: {}", display, - why.description()), + Err(why) => panic!("couldn't open {}: {}", display, why), Ok(file) => file, }; // Read the file contents into a string, returns `io::Result` let mut s = String::new(); match file.read_to_string(&mut s) { - Err(why) => panic!("couldn't read {}: {}", display, - why.description()), + Err(why) => panic!("couldn't read {}: {}", display, why), Ok(_) => print!("{} contains:\n{}", display, s), } // `file` goes out of scope, and the "hello.txt" file gets closed } - ``` Here's the expected successful output: diff --git a/src/std_misc/process/pipe.md b/src/std_misc/process/pipe.md index aeba29d2f5..fb0be0ea11 100644 --- a/src/std_misc/process/pipe.md +++ b/src/std_misc/process/pipe.md @@ -5,7 +5,6 @@ The `std::Child` struct represents a running child process, and exposes the process via pipes. ```rust,ignore -use std::error::Error; use std::io::prelude::*; use std::process::{Command, Stdio}; @@ -18,7 +17,7 @@ fn main() { .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() { - Err(why) => panic!("couldn't spawn wc: {}", why.description()), + Err(why) => panic!("couldn't spawn wc: {}", why), Ok(process) => process, }; @@ -27,8 +26,7 @@ fn main() { // `stdin` has type `Option`, but since we know this instance // must have one, we can directly `unwrap` it. match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { - Err(why) => panic!("couldn't write to wc stdin: {}", - why.description()), + Err(why) => panic!("couldn't write to wc stdin: {}", why), Ok(_) => println!("sent pangram to wc"), } @@ -41,8 +39,7 @@ fn main() { // The `stdout` field also has type `Option` so must be unwrapped. let mut s = String::new(); match process.stdout.unwrap().read_to_string(&mut s) { - Err(why) => panic!("couldn't read wc stdout: {}", - why.description()), + Err(why) => panic!("couldn't read wc stdout: {}", why), Ok(_) => print!("wc responded with:\n{}", s), } } From 4c897e3feb67101b16d225562c36cfa6157986f7 Mon Sep 17 00:00:00 2001 From: olehmisar Date: Sun, 22 Mar 2020 19:43:18 +0200 Subject: [PATCH 1012/1122] Remove unnecessary `impl std::error::Error` --- src/error/multiple_error_types/define_error_type.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/error/multiple_error_types/define_error_type.md b/src/error/multiple_error_types/define_error_type.md index 45e5766690..4c374276dc 100644 --- a/src/error/multiple_error_types/define_error_type.md +++ b/src/error/multiple_error_types/define_error_type.md @@ -16,7 +16,6 @@ Rust allows us to define our own error types. In general, a "good" error type: * Composes well with other errors ```rust,editable -use std::error; use std::fmt; type Result = std::result::Result; @@ -38,14 +37,6 @@ impl fmt::Display for DoubleError { } } -// This is important for other errors to wrap this one. -impl error::Error for DoubleError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - // Generic error, underlying cause isn't tracked. - None - } -} - fn double_first(vec: Vec<&str>) -> Result { vec.first() // Change the error to our new type. From bef631134756d1244e4d2ef513d2ad6633559498 Mon Sep 17 00:00:00 2001 From: Naja Melan Date: Mon, 23 Mar 2020 15:24:22 +0100 Subject: [PATCH 1013/1122] Rewrite section on 'static lifetime. This tries to be more precise and in specific help avoid confusion about 'static trait bounds. --- src/scope/lifetime/static_lifetime.md | 78 +++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index 46d81117c8..7a1bddfa0f 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -1,10 +1,27 @@ # Static -A `'static` lifetime is the longest possible lifetime, and lasts for -the lifetime of the running program. A `'static` lifetime may also be -coerced to a shorter lifetime. There are two ways to make a variable -with `'static` lifetime, and both are stored in the read-only memory -of the binary: +Rust has a few reserved lifetime names. One of those is `'static`. You +might encounter it in two situations: + +```rust, editable +// A reference with 'static lifetime: +let s: &'static str = "hello world"; + +// 'static as part of a trait bound: +fn generic(x: T) where T: 'static {} +``` + +Both are related but subtly different and this is a common source for +confusion when learning Rust. Here are some examples for each situation: + +## Reference lifetime + +As a reference lifetime `'static` indicates that the data pointed to by +the reference lives for the entire lifetime of the running program. +It can still be coerced to a shorter lifetime. + +There are two ways to make a variable with `'static` lifetime, and both +are stored in the read-only memory of the binary: * Make a constant with the `static` declaration. * Make a `string` literal which has type: `&'static str`. @@ -15,7 +32,7 @@ See the following example for a display of each method: // Make a constant with `'static` lifetime. static NUM: i32 = 18; -// Returns a reference to `NUM` where its `'static` +// Returns a reference to `NUM` where its `'static` // lifetime is coerced to that of the input argument. fn coerce_static<'a>(_: &'a i32) -> &'a i32 { &NUM @@ -30,7 +47,7 @@ fn main() { // When `static_string` goes out of scope, the reference // can no longer be used, but the data remains in the binary. } - + { // Make an integer to use for `coerce_static`: let lifetime_num = 9; @@ -40,13 +57,56 @@ fn main() { println!("coerced_static: {}", coerced_static); } - + println!("NUM: {} stays accessible!", NUM); } ``` +## Trait bound + +As a trait bound, it means the type does not contain any non-static +references. Eg. the receiver can hold on to the type for as long as +they want and it will never become invalid until they drop it. + +It's important to understand this means that any owned data always passes +a `'static` lifetime bound, but a reference to that owned data generally +does not: + +```rust,editable,compile_fail +use std::fmt::Debug; + +fn print_it( input: impl Debug + 'static ) +{ + println!( "'static value passed in is: {:?}", input ); +} + +fn use_it() +{ + // i is owned and contains no references, thus it's 'static: + let i = 5; + print_it(i); + + // oops, &i only has the lifetime defined by the scope of + // use_it(), so it's not 'static: + print_it(&i); +} +``` +The compiler will tell you: +```ignore +error[E0597]: `i` does not live long enough + --> src/lib.rs:15:15 + | +15 | print_it(&i); + | ---------^^-- + | | | + | | borrowed value does not live long enough + | argument requires that `i` is borrowed for `'static` +16 | } + | - `i` dropped here while still borrowed +``` + ### See also: [`'static` constants][static_const] -[static_const]: ../../custom_types/constants.md \ No newline at end of file +[static_const]: ../../custom_types/constants.md From ffa4464d02240b576b777d6ca7d253960a494323 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 25 Mar 2020 12:48:47 -0700 Subject: [PATCH 1014/1122] fix: make spelling/style of rustdoc consistent --- src/meta/doc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index 4aa2cbf0cc..866c976d8a 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -9,7 +9,7 @@ These commands will appropriately invoke `rustdoc` (and `rustc`) as required. ### Doc comments Doc comments are very useful for big projects that require documentation. When -running Rustdoc, these are the comments that get compiled into +running `rustdoc`, these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown]. ```rust,editable,ignore @@ -32,7 +32,7 @@ impl Person { /// /// ``` /// // You can have rust code between fences inside the comments - /// // If you pass --test to Rustdoc, it will even test it for you! + /// // If you pass --test to `rustdoc`, it will even test it for you! /// use doc::Person; /// let person = Person::new("name"); /// ``` @@ -57,7 +57,7 @@ fn main() { } ``` -To run the tests, first build the code as a library, then tell rustdoc where +To run the tests, first build the code as a library, then tell `rustdoc` where to find the library so it can link it into each doctest program: ```shell @@ -68,7 +68,7 @@ $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ### See also: * [The Rust Book: Making Useful Documentation Comments][book] -* [The Rustdoc Book][rustdoc-book] +* [The rustdoc Book][rustdoc-book] * [The Reference: Doc comments][ref-comments] * [RFC 1574: API Documentation Conventions][api-conv] * [RFC 1946: Relative links to other items from doc comments (intra-rustdoc links)][intra-links] From 4aae06a29a17461cb5de95b6d76c7d4ebe30b72c Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 25 Mar 2020 13:49:47 -0700 Subject: [PATCH 1015/1122] feat: add sentence about rustdoc & std library --- src/meta/doc.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/meta/doc.md b/src/meta/doc.md index 4aa2cbf0cc..a3cc4b73b1 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -65,6 +65,8 @@ $ rustc doc.rs --crate-type lib $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` +For documentation, `rustdoc` is widely used by the community. It's what is used to generate the [std library docs](https://doc.rust-lang.org/std/). + ### See also: * [The Rust Book: Making Useful Documentation Comments][book] From 6a0cdb0ef7f964594eec1d99bef5f172751499a5 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 25 Mar 2020 14:50:26 -0700 Subject: [PATCH 1016/1122] feat: add doc attributes section to documentation --- src/meta/doc.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index 4aa2cbf0cc..444b00e07e 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -6,7 +6,7 @@ Use `cargo test` to run all tests (including documentation tests), and `cargo te These commands will appropriately invoke `rustdoc` (and `rustc`) as required. -### Doc comments +## Doc comments Doc comments are very useful for big projects that require documentation. When running Rustdoc, these are the comments that get compiled into @@ -65,6 +65,43 @@ $ rustc doc.rs --crate-type lib $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` +## Doc attributes + +Below are a few examples of the most common `#[doc]` attributes used with `rustdoc`. + +### `inline` + +Used to inline docs, instead of linking out to separate page. + +```rust +#[doc(inline)] +pub use bar::Bar; + +/// bar docs +mod bar { + /// the docs for Bar + pub struct Bar; +} +``` + +### `no_inline` +Used to prevent linking out to separate page or anywhere. + +```rust +// Example from libcore/prelude +#[doc(no_inline)] +pub use crate::mem::drop; +``` + +### `hidden` + +Using this tells `rustdoc` not to include this in documentation: +```rust,editable +// Example from the futures-rs library +#[doc(hidden)] +pub use self::async_await::*; +``` + ### See also: * [The Rust Book: Making Useful Documentation Comments][book] From 94ca1f7d667c8f67f8bc4743322347f83a534c2f Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 25 Mar 2020 14:53:46 -0700 Subject: [PATCH 1017/1122] Update src/meta/doc.md --- src/meta/doc.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meta/doc.md b/src/meta/doc.md index 444b00e07e..7ca6458c29 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -85,6 +85,7 @@ mod bar { ``` ### `no_inline` + Used to prevent linking out to separate page or anywhere. ```rust From 06bad89098cc76d9d60b99f2a1f49f9735c7a6a2 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sat, 28 Mar 2020 09:01:42 -0700 Subject: [PATCH 1018/1122] refactor: remove testing & benchmarking from meta --- src/meta.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/meta.md b/src/meta.md index f5119d5f41..7c87572258 100644 --- a/src/meta.md +++ b/src/meta.md @@ -4,9 +4,5 @@ Some topics aren't exactly relevant to how you program but provide you tooling or infrastructure support which just makes things better for everyone. These topics include: -* Documentation: Generate library documentation for users via the included -`rustdoc`. -* Testing: Create testsuites for libraries to give confidence that your -library does exactly what it's supposed to. -* Benchmarking: Create benchmarks for functionality to be confident that -they run quickly. +- Documentation: Generate library documentation for users via the included + `rustdoc`. From 2070064cb7df1712ab9658880104777199e08c29 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sat, 28 Mar 2020 09:02:28 -0700 Subject: [PATCH 1019/1122] fix: add .DS_Stoe to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7585238efe..e82f879ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ book + +# Auto-generated files from macOS +.DS_Store \ No newline at end of file From ef4ad08b861e0003e712ed1502ee737ed38cfb7d Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sat, 28 Mar 2020 09:05:32 -0700 Subject: [PATCH 1020/1122] feat: add link in meta to documentation --- src/meta.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/meta.md b/src/meta.md index 7c87572258..a093d4ba07 100644 --- a/src/meta.md +++ b/src/meta.md @@ -4,5 +4,7 @@ Some topics aren't exactly relevant to how you program but provide you tooling or infrastructure support which just makes things better for everyone. These topics include: -- Documentation: Generate library documentation for users via the included +- [Documentation][doc]: Generate library documentation for users via the included `rustdoc`. + +[doc]: meta/doc.md From 9827595857633969870c919fde1f051103813119 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sat, 28 Mar 2020 09:56:37 -0700 Subject: [PATCH 1021/1122] feat: add playpen topic --- src/SUMMARY.md | 1 + src/meta/playpen.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/meta/playpen.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3e3e0aa319..7e00336d6b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -213,3 +213,4 @@ - [Meta](meta.md) - [Documentation](meta/doc.md) + - [Playpen](meta/playpen.md) diff --git a/src/meta/playpen.md b/src/meta/playpen.md new file mode 100644 index 0000000000..e8706752cc --- /dev/null +++ b/src/meta/playpen.md @@ -0,0 +1,38 @@ +# Playpen + +The [Rust Playpen](https://github.com/rust-lang/rust-playpen) is a way to experiment with Rust code through a web interface. This project is now commonly referred to as [Rust Playground](https://play.rust-lang.org/). + +## Using it with `mdbook` + +In [`mdbook`][mdbook], you can make code examples playable and editable. + +```rust,editable +fn main() { + println!("Hello World!"); +} +``` + +This allows the reader to both run your code sample, but also modify and tweak it. The key here is the adding the word `editable` to your codefence block separated by a comma. + +````markdown +```rust,editable +//...place your code here +``` +```` + +## Using it with docs + +You may have noticed in some of the [official Rust docs][official-rust-docs] a button that says "Run", which opens the code sample up in a new tab in Rust Playground. This feature is enabled if you use the #[doc] attribute called [`html_playground_url`][html-playground-url]. + +### See also: + +- [The Rust Playground][rust-playground] +- [The next-gen playpen][next-gen-playpen] +- [The rustdoc Book][rustdoc-book] + +[rust-playground]: https://play.rust-lang.org/ +[next-gen-playpen]: https://github.com/integer32llc/rust-playground/ +[mdbook]: https://github.com/rust-lang/mdBook +[official-rust-docs]: https://doc.rust-lang.org/core/ +[rustdoc-book]: https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html +[html-playground-url]: https://doc.rust-lang.org/rustdoc/the-doc-attribute.html#html_playground_url From 3e42f06ce669112ea4532bc67f819eec3f896391 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sat, 28 Mar 2020 09:56:46 -0700 Subject: [PATCH 1022/1122] feat: add playpen topic to meta --- src/meta.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/meta.md b/src/meta.md index a093d4ba07..a7434521c7 100644 --- a/src/meta.md +++ b/src/meta.md @@ -6,5 +6,7 @@ everyone. These topics include: - [Documentation][doc]: Generate library documentation for users via the included `rustdoc`. +- [Playpen][playpen]: Integrate the Rust Playpen(also known as the Rust Playground) in your documentation. [doc]: meta/doc.md +[playpen]: meta/playpen.md From 4324f2e5c8ee5873ab2b10dfb265b881a6026a35 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 25 Mar 2020 14:50:26 -0700 Subject: [PATCH 1023/1122] feat: add doc attributes section to documentation --- src/meta/doc.md | 59 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index cd60abb21c..f4051799db 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -6,13 +6,13 @@ Use `cargo test` to run all tests (including documentation tests), and `cargo te These commands will appropriately invoke `rustdoc` (and `rustc`) as required. -### Doc comments +## Doc comments Doc comments are very useful for big projects that require documentation. When running `rustdoc`, these are the comments that get compiled into documentation. They are denoted by a `///`, and support [Markdown]. -```rust,editable,ignore +````rust,editable,ignore #![crate_name = "doc"] /// A human being is represented here @@ -55,7 +55,7 @@ fn main() { john.hello(); } -``` +```` To run the tests, first build the code as a library, then tell `rustdoc` where to find the library so it can link it into each doctest program: @@ -65,18 +65,55 @@ $ rustc doc.rs --crate-type lib $ rustdoc --test --extern doc="libdoc.rlib" doc.rs ``` -For documentation, `rustdoc` is widely used by the community. It's what is used to generate the [std library docs](https://doc.rust-lang.org/std/). +## Doc attributes + +Below are a few examples of the most common `#[doc]` attributes used with `rustdoc`. + +### `inline` + +Used to inline docs, instead of linking out to separate page. + +```rust +#[doc(inline)] +pub use bar::Bar; + +/// bar docs +mod bar { + /// the docs for Bar + pub struct Bar; +} +``` + +### `no_inline` + +Used to prevent linking out to separate page or anywhere. + +```rust +// Example from libcore/prelude +#[doc(no_inline)] +pub use crate::mem::drop; +``` + +### `hidden` + +Using this tells `rustdoc` not to include this in documentation: + +```rust,editable +// Example from the futures-rs library +#[doc(hidden)] +pub use self::async_await::*; +``` ### See also: -* [The Rust Book: Making Useful Documentation Comments][book] -* [The rustdoc Book][rustdoc-book] -* [The Reference: Doc comments][ref-comments] -* [RFC 1574: API Documentation Conventions][api-conv] -* [RFC 1946: Relative links to other items from doc comments (intra-rustdoc links)][intra-links] -* [Is there any documentation style guide for comments? (reddit)][reddit] +- [The Rust Book: Making Useful Documentation Comments][book] +- [The rustdoc Book][rustdoc-book] +- [The Reference: Doc comments][ref-comments] +- [RFC 1574: API Documentation Conventions][api-conv] +- [RFC 1946: Relative links to other items from doc comments (intra-rustdoc links)][intra-links] +- [Is there any documentation style guide for comments? (reddit)][reddit] -[Markdown]: https://en.wikipedia.org/wiki/Markdown +[markdown]: https://en.wikipedia.org/wiki/Markdown [book]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments [ref-comments]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments [rustdoc-book]: https://doc.rust-lang.org/rustdoc/index.html From 051382af6e603cac434b72780a0c0c9b76d2aa5b Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sun, 29 Mar 2020 15:04:26 -0700 Subject: [PATCH 1024/1122] fix: ignore code examples in doc --- src/meta/doc.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index c51a767499..da6ff9ea8c 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -73,7 +73,7 @@ Below are a few examples of the most common `#[doc]` attributes used with `rustd Used to inline docs, instead of linking out to separate page. -```rust +```rust,ignore #[doc(inline)] pub use bar::Bar; @@ -88,7 +88,7 @@ mod bar { Used to prevent linking out to separate page or anywhere. -```rust +```rust,ignore // Example from libcore/prelude #[doc(no_inline)] pub use crate::mem::drop; @@ -98,7 +98,7 @@ pub use crate::mem::drop; Using this tells `rustdoc` not to include this in documentation: -```rust,editable +```rust,editable,ignore // Example from the futures-rs library #[doc(hidden)] pub use self::async_await::*; From 5382d4b7bbaa4e48b922c94e3c0848b9f44e3af1 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Sun, 29 Mar 2020 15:04:40 -0700 Subject: [PATCH 1025/1122] feat: add example with ignore to playpen --- src/meta/playpen.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/meta/playpen.md b/src/meta/playpen.md index e8706752cc..a125f139d8 100644 --- a/src/meta/playpen.md +++ b/src/meta/playpen.md @@ -20,6 +20,14 @@ This allows the reader to both run your code sample, but also modify and tweak i ``` ```` +Additionally, you can add `ignore` if you want `mdbook` to skip your code when it builds and tests. + +````markdown +```rust,editable,ignore +//...place your code here +``` +```` + ## Using it with docs You may have noticed in some of the [official Rust docs][official-rust-docs] a button that says "Run", which opens the code sample up in a new tab in Rust Playground. This feature is enabled if you use the #[doc] attribute called [`html_playground_url`][html-playground-url]. From fc1265287146e573db780eb8da42d5a029023f50 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Mar 2020 11:29:54 -0400 Subject: [PATCH 1026/1122] Add triagebot configuration This enables assignment through triagebot on this repository, in preparation for the migration from highfive to triagebot for PR assignment. --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 triagebot.toml diff --git a/triagebot.toml b/triagebot.toml new file mode 100644 index 0000000000..fa0824ac53 --- /dev/null +++ b/triagebot.toml @@ -0,0 +1 @@ +[assign] From 2876b85ec05ff61a2f6a60f437a1cf8c948a0fc2 Mon Sep 17 00:00:00 2001 From: Ross MacArthur Date: Sun, 5 Apr 2020 14:37:51 +0200 Subject: [PATCH 1027/1122] Do not use "nil" to refer to `()` --- src/custom_types/structs.md | 4 ++-- src/trait/clone.md | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index e863e0ee6b..b7f84c2fa4 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -16,7 +16,7 @@ struct Person<'a> { } // A unit struct -struct Nil; +struct Unit; // A tuple struct struct Pair(i32, f32); @@ -70,7 +70,7 @@ fn main() { }; // Instantiate a unit struct - let _nil = Nil; + let _unit = Unit; // Instantiate a tuple struct let pair = Pair(1, 0.1); diff --git a/src/trait/clone.md b/src/trait/clone.md index acd531632a..1b9d953b71 100644 --- a/src/trait/clone.md +++ b/src/trait/clone.md @@ -1,30 +1,30 @@ # Clone When dealing with resources, the default behavior is to transfer them during -assignments or function calls. However, sometimes we need to make a +assignments or function calls. However, sometimes we need to make a copy of the resource as well. -The [`Clone`][clone] trait helps us do exactly this. Most commonly, we can +The [`Clone`][clone] trait helps us do exactly this. Most commonly, we can use the `.clone()` method defined by the `Clone` trait. ```rust,editable // A unit struct without resources #[derive(Debug, Clone, Copy)] -struct Nil; +struct Unit; // A tuple struct with resources that implements the `Clone` trait #[derive(Clone, Debug)] struct Pair(Box, Box); fn main() { - // Instantiate `Nil` - let nil = Nil; - // Copy `Nil`, there are no resources to move - let copied_nil = nil; + // Instantiate `Unit` + let unit = Unit; + // Copy `Unit`, there are no resources to move + let copied_unit = unit; - // Both `Nil`s can be used independently - println!("original: {:?}", nil); - println!("copy: {:?}", copied_nil); + // Both `Unit`s can be used independently + println!("original: {:?}", unit); + println!("copy: {:?}", copied_unit); // Instantiate `Pair` let pair = Pair(Box::new(1), Box::new(2)); @@ -37,7 +37,7 @@ fn main() { // Error! `pair` has lost its resources //println!("original: {:?}", pair); // TODO ^ Try uncommenting this line - + // Clone `moved_pair` into `cloned_pair` (resources are included) let cloned_pair = moved_pair.clone(); // Drop the original pair using std::mem::drop @@ -52,4 +52,4 @@ fn main() { } ``` -[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html \ No newline at end of file +[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html From 3a2e962316f997cacd52fbe59df9aeb387f3ceb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 01:47:42 +0200 Subject: [PATCH 1028/1122] Use T::MAX instead of std::T::MAX where T is an integer --- src/types/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/cast.md b/src/types/cast.md index e455b81f23..350f9d6fe6 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -25,7 +25,7 @@ fn main() { println!("Casting: {} -> {} -> {}", decimal, integer, character); // when casting any value to an unsigned type, T, - // std::T::MAX + 1 is added or subtracted until the value + // T::MAX + 1 is added or subtracted until the value // fits into the new type // 1000 already fits in a u16 From d6d87699c9f57a0deb9a15e246dc7dfd5e2a0395 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 8 Apr 2020 22:25:35 +0000 Subject: [PATCH 1029/1122] Add an example of casting error --- src/types/cast.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/types/cast.md b/src/types/cast.md index 350f9d6fe6..7d990976a3 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -22,6 +22,10 @@ fn main() { let integer = decimal as u8; let character = integer as char; + // Error! There are limitations in conversion rules. A float cannot be directly converted to a char. + let character = decimal as char; + // FIXME ^ Comment out this line + println!("Casting: {} -> {} -> {}", decimal, integer, character); // when casting any value to an unsigned type, T, From cb328e7a8b58225d99daec2e20eaa28cee6900c8 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 8 Apr 2020 22:26:04 +0000 Subject: [PATCH 1030/1122] Reference the casting doc for primitive conversions --- src/conversion.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/conversion.md b/src/conversion.md index 78d9e2d31e..52a96d06c4 100644 --- a/src/conversion.md +++ b/src/conversion.md @@ -1,10 +1,14 @@ # Conversion -Rust addresses conversion between types by the use of [traits]. The generic +Primitive types can be converted to each other through [casting]. + +Rust addresses conversion between custom types (i.e., `struct` and `enum`) +by the use of [traits]. The generic conversions will use the [`From`] and [`Into`] traits. However there are more specific ones for the more common cases, in particular when converting to and from `String`s. +[casting]: types/cast.md [traits]: trait.md [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html From 634e6f6a1cd08f9d20a851040c4b77a1cc65c47e Mon Sep 17 00:00:00 2001 From: Ashok Gautham Date: Thu, 9 Apr 2020 19:16:40 +0530 Subject: [PATCH 1031/1122] Capture example should use String Using a `&'static str` like "green" would not prevent us from using the closure `print` post the move. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=411cb0b9776ece079c97d820ea6733ee --- src/fn/closures/capture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/closures/capture.md b/src/fn/closures/capture.md index d4fa4eadc9..061ef1c7b2 100644 --- a/src/fn/closures/capture.md +++ b/src/fn/closures/capture.md @@ -16,7 +16,7 @@ required. fn main() { use std::mem; - let color = "green"; + let color = String::from("green"); // A closure to print `color` which immediately borrows (`&`) `color` and // stores the borrow and closure in the `print` variable. It will remain From 8019a29810d1c6207ec01bae8015f7a446d77dac Mon Sep 17 00:00:00 2001 From: Toshiki Kataoka Date: Wed, 15 Apr 2020 18:06:12 +0900 Subject: [PATCH 1032/1122] Fix bytes of youkoso in shiftjis --- src/std/str.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/str.md b/src/std/str.md index 9f4d7105e1..ba14b59db1 100644 --- a/src/std/str.md +++ b/src/std/str.md @@ -145,7 +145,7 @@ fn main() { like with normal raw strings"#; // Byte strings don't have to be UTF-8 - let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82"; // "ようこそ" in SHIFT-JIS + let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // "ようこそ" in SHIFT-JIS // But then they can't always be converted to `str` match str::from_utf8(shift_jis) { From 7ab1e8919ca36b77da0bee8ed3a2cfa256e50795 Mon Sep 17 00:00:00 2001 From: Lee Yi Jie Joel Date: Wed, 15 Apr 2020 17:40:08 +0800 Subject: [PATCH 1033/1122] Fix possible typo --- src/generics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics.md b/src/generics.md index d1ecca5574..86ecc581a9 100644 --- a/src/generics.md +++ b/src/generics.md @@ -58,7 +58,7 @@ fn main() { ### See also: -[`struct`s][structs] +[`structs`][structs] [structs]: custom_types/structs.md [camelcase]: https://en.wikipedia.org/wiki/CamelCase From 6642d08cefcac388cfb314725f0d5a7e9ea663a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Karabulut?= Date: Wed, 15 Apr 2020 14:05:06 +0300 Subject: [PATCH 1034/1122] Make unsuffixed literal plural Because we have multiple unsuffixed literals and we refer the corresponding types as their types, make it plural. --- src/types/literals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/literals.md b/src/types/literals.md index 78aa67fbe3..61f477e7ed 100644 --- a/src/types/literals.md +++ b/src/types/literals.md @@ -14,7 +14,7 @@ fn main() { let y = 2u32; let z = 3f32; - // Unsuffixed literal, their types depend on how they are used + // Unsuffixed literals, their types depend on how they are used let i = 1; let f = 1.0; From 0eac05a853ab7c4ce33dba223ed113c79a2ea390 Mon Sep 17 00:00:00 2001 From: Sam Bernard Date: Sat, 18 Apr 2020 17:34:57 -0600 Subject: [PATCH 1035/1122] Ensure example error matches the comment Replace the trailing semicolon with a comma, so that RLS raises an error about "pattern does not mention field `x`" instead of "expected one of `,`, `.`, `?`, `}`, or an operator, found `;`" --- src/flow_control/match/destructuring/destructure_structures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index 35ce28db87..135b33cc19 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -22,7 +22,7 @@ fn main() { // and you can also ignore some variables: Foo { y, .. } => println!("y = {}, we don't care about x", y), // this will give an error: pattern does not mention field `x` - //Foo { y } => println!("y = {}", y); + //Foo { y } => println!("y = {}", y), } } ``` From 758278a61223229335ea83a015c74d5bf965c85d Mon Sep 17 00:00:00 2001 From: Olivier ROLAND Date: Wed, 22 Apr 2020 22:57:05 +0200 Subject: [PATCH 1036/1122] Clarifies how to customize lib crate name --- src/crates/lib.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/crates/lib.md b/src/crates/lib.md index 92eddc6ac6..20b4cac59e 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -25,7 +25,8 @@ library.rlib ``` Libraries get prefixed with "lib", and by default they get named after their -crate file, but this default name can be overridden using the [`crate_name` +crate file, but this default name can be overridden by passing +the `--crate-name` option to `rustc` or by using the [`crate_name` attribute][crate-name]. [crate-name]: ../attribute/crate.md \ No newline at end of file From a8293dc182bca94a089dd90daa99ba3629a6c498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Karabulut?= Date: Thu, 23 Apr 2020 23:12:18 +0300 Subject: [PATCH 1037/1122] Add missing triple backticks Ending tiple backticks are missing in the doc testing example. Add these backticks. --- src/testing/doc_testing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/testing/doc_testing.md b/src/testing/doc_testing.md index 1896ca556b..642cbe8a58 100644 --- a/src/testing/doc_testing.md +++ b/src/testing/doc_testing.md @@ -89,6 +89,7 @@ to the rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it a /// # try_main().unwrap(); // calling try_main and unwrapping /// # // so that test will panic in case of error /// # } +/// ``` pub fn try_div(a: i32, b: i32) -> Result { if b == 0 { Err(String::from("Divide-by-zero")) From c73229535b6fc098ebf7fba31f35b5ba8b442760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Karabulut?= Date: Thu, 23 Apr 2020 23:49:03 +0300 Subject: [PATCH 1038/1122] Fix Example -> Examples As suggested by RFC505, use the plural form: "Examples" rather than "Example" even for one example. --- src/meta/doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meta/doc.md b/src/meta/doc.md index da6ff9ea8c..63e0b41018 100644 --- a/src/meta/doc.md +++ b/src/meta/doc.md @@ -28,7 +28,7 @@ impl Person { /// /// * `name` - A string slice that holds the name of the person /// - /// # Example + /// # Examples /// /// ``` /// // You can have rust code between fences inside the comments From b4bf16bfce56f65d7ed96c69f7a2715fa26164d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Karabulut?= Date: Thu, 23 Apr 2020 22:33:13 +0300 Subject: [PATCH 1039/1122] Clarify conditional compilation Introduction of `cfg` attribute and `cfg!` macro operators can be confusing. `cfg!` macro and `cfg` attribute behave differently in terms of conditional compilation. While `cfg` attribute enables conditional compilation of some code, `cfg!` macro conditionally evaluates to `true` or `false` literals for run-time checks. --- src/attribute/cfg.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/attribute/cfg.md b/src/attribute/cfg.md index 1b20e12f4d..d0a4a10b73 100644 --- a/src/attribute/cfg.md +++ b/src/attribute/cfg.md @@ -1,11 +1,13 @@ # `cfg` -Conditional compilation is possible through two different operators: +Configuration conditional checks are possible through two different operators: * the `cfg` attribute: `#[cfg(...)]` in attribute position * the `cfg!` macro: `cfg!(...)` in boolean expressions -Both utilize identical argument syntax. +While the former enables conditional compilation, the latter conditionally +evaluates to `true` or `false` literals allowing for checks at run-time. Both +utilize identical argument syntax. ```rust,editable // This function only gets compiled if the target OS is linux @@ -22,7 +24,7 @@ fn are_you_on_linux() { fn main() { are_you_on_linux(); - + println!("Are you sure?"); if cfg!(target_os = "linux") { println!("Yes. It's definitely linux!"); From ded28f6477cc3cdcfa6e2f294e06e45c5aaa283b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Karabulut?= Date: Sun, 26 Apr 2020 11:05:10 +0300 Subject: [PATCH 1040/1122] Fix empty bound examples Unlike `std::cmp::Eq`, `std::cmp::Ord` is not an empty bound. Therefore, replace it with an empty bound, `std::marker::Copy`. --- src/generics/bounds/testcase_empty.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/generics/bounds/testcase_empty.md b/src/generics/bounds/testcase_empty.md index df4904a3d5..e956a57e42 100644 --- a/src/generics/bounds/testcase_empty.md +++ b/src/generics/bounds/testcase_empty.md @@ -2,7 +2,7 @@ A consequence of how bounds work is that even if a `trait` doesn't include any functionality, you can still use it as a bound. `Eq` and -`Ord` are examples of such `trait`s from the `std` library. +`Copy` are examples of such `trait`s from the `std` library. ```rust,editable struct Cardinal; @@ -36,8 +36,8 @@ fn main() { ### See also: -[`std::cmp::Eq`][eq], [`std::cmp::Ord`s][ord], and [`trait`s][traits] +[`std::cmp::Eq`][eq], [`std::marker::Copy`][copy], and [`trait`s][traits] [eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html -[ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html +[copy]: https://doc.rust-lang.org/std/marker/trait.Copy.html [traits]: ../../trait.md From 680c9d8f97ba36aefe23ef2fdaea202b0c536cc5 Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Mon, 27 Apr 2020 02:10:34 +0900 Subject: [PATCH 1041/1122] Fix an inline comment in macros/repeat.md --- src/macros/repeat.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macros/repeat.md b/src/macros/repeat.md index a3431ef51c..04c3b7da66 100644 --- a/src/macros/repeat.md +++ b/src/macros/repeat.md @@ -9,7 +9,7 @@ match one or more expression, separated by commas. Also note that the semicolon is optional on the last case. ```rust,editable -// `min!` will calculate the minimum of any number of arguments. +// `find_min!` will calculate the minimum of any number of arguments. macro_rules! find_min { // Base case: ($x:expr) => ($x); @@ -25,4 +25,4 @@ fn main() { println!("{}", find_min!(1u32 + 2, 2u32)); println!("{}", find_min!(5u32, 2u32 * 3, 4u32)); } -``` \ No newline at end of file +``` From bfd7f2733d5cc2a05fd9587d7a7e7dcab14e17ee Mon Sep 17 00:00:00 2001 From: Ozgur Murat Date: Tue, 5 May 2020 14:23:04 +0300 Subject: [PATCH 1042/1122] Remove stale footnote Footnote about function 'fun' is not in source code. --- src/types/literals.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/literals.md b/src/types/literals.md index 61f477e7ed..fd26b9dcaf 100644 --- a/src/types/literals.md +++ b/src/types/literals.md @@ -30,14 +30,11 @@ fn main() { There are some concepts used in the previous code that haven't been explained yet, here's a brief explanation for the impatient readers: -* `fun(&foo)` is used to pass an argument to a function *by reference*, rather - than by value (`fun(foo)`). For more details see [borrowing][borrow]. * `std::mem::size_of_val` is a function, but called with its *full path*. Code can be split in logical units called *modules*. In this case, the `size_of_val` function is defined in the `mem` module, and the `mem` module is defined in the `std` *crate*. For more details, see [modules][mod] and [crates][crate]. -[borrow]: ../scope/borrow.md [mod]: ../mod.md [crate]: ../crates.md From 701919b5d09eae919348d086d496ce23f9578301 Mon Sep 17 00:00:00 2001 From: hsi <53867065+username@users.noreply.github.com> Date: Sat, 9 May 2020 13:14:19 +0200 Subject: [PATCH 1043/1122] Fix link of formatting traits --- src/hello/print.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index 6efa8eb711..afc72537de 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -89,6 +89,6 @@ and [`traits`][traits] [macros]: ../macros.md [string]: ../std/str.md [structs]: ../custom_types/structs.md -[traits]: ../trait.md +[traits]: https://doc.rust-lang.org/std/fmt/#formatting-traits [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html [convert]: ../conversion/string.md From 073488272f398a33da1b68c6ab7a3c2456d71382 Mon Sep 17 00:00:00 2001 From: Roman Levin Date: Sat, 16 May 2020 23:01:18 +0200 Subject: [PATCH 1044/1122] Gramatical fix in std/rc.md --- src/std/rc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/rc.md b/src/std/rc.md index 358bd45f39..86e00e9081 100644 --- a/src/std/rc.md +++ b/src/std/rc.md @@ -4,7 +4,7 @@ When multiple ownership is needed, `Rc`(Reference Counting) can be used. `Rc` ke Reference count of an `Rc` increases by 1 whenever an `Rc` is cloned, and decreases by 1 whenever one cloned `Rc` is dropped out of the scope. When an `Rc`'s reference count becomes zero, which means there are no owners remained, both the `Rc` and the value are all dropped. -Cloning an `Rc` never do a deep copy. Cloning creates just another pointer to the wrapped value, and increments the count. +Cloning an `Rc` never performs a deep copy. Cloning creates just another pointer to the wrapped value, and increments the count. ```rust,editable use std::rc::Rc; From 91aeab9ce9a18158f2a542ad5f75d5796aa80e43 Mon Sep 17 00:00:00 2001 From: Andrew Lygin Date: Mon, 25 May 2020 20:33:41 +0300 Subject: [PATCH 1045/1122] Person of age 0 is alive A person is of age 0 right after he or she was born, and before the first birthday. --- src/flow_control/match/binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/match/binding.md b/src/flow_control/match/binding.md index 0407b37774..ccbb7c2add 100644 --- a/src/flow_control/match/binding.md +++ b/src/flow_control/match/binding.md @@ -14,7 +14,7 @@ fn main() { println!("Tell me what type of person you are"); match age() { - 0 => println!("I'm not born yet I guess"), + 0 => println!("I haven't celebrated my first birthday yet"), // Could `match` 1 ..= 12 directly but then what age // would the child be? Instead, bind to `n` for the // sequence of 1 ..= 12. Now the age can be reported. From 64f9126fbea2f257f7fcf2c75a13c7da3d8c45d3 Mon Sep 17 00:00:00 2001 From: zancas Date: Mon, 8 Jun 2020 13:46:00 -0600 Subject: [PATCH 1046/1122] This explanation incorrectly inverts the meaning of SuperTrait --- src/trait/supertraits.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trait/supertraits.md b/src/trait/supertraits.md index b28b8f4c9d..b1e10e10ed 100644 --- a/src/trait/supertraits.md +++ b/src/trait/supertraits.md @@ -8,7 +8,7 @@ trait Person { fn name(&self) -> String; } -// Student is a supertrait of Person. +// Person is a supertrait of Student. // Implementing Student requires you to also impl Person. trait Student: Person { fn university(&self) -> String; @@ -18,8 +18,8 @@ trait Programmer { fn fav_language(&self) -> String; } -// CompSciStudent (computer science student) is a supertrait of both Programmer -// and Student. Implementing CompSciStudent requires you to impl both subtraits. +// CompSciStudent (computer science student) is a subtrait of both Programmer +// and Student. Implementing CompSciStudent requires you to impl both supertraits. trait CompSciStudent: Programmer + Student { fn git_username(&self) -> String; } From c59cd59b6a49384a02216fc77943839bcfa85148 Mon Sep 17 00:00:00 2001 From: Nihaal Sangha <18350092+nihaals@users.noreply.github.com> Date: Sun, 14 Jun 2020 09:28:54 +0100 Subject: [PATCH 1047/1122] Fixed typo --- src/hello/print.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index afc72537de..e09f128ebc 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -64,7 +64,7 @@ of text. The base form of two important ones are listed below: * `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user friendly fashion. -Here, we used `fmt::Display `because the std library provides implementations +Here, we used `fmt::Display` because the std library provides implementations for these types. To print text for custom types, more steps are required. Implementing the `fmt::Display` trait automatically implements the From 1b0138a67da001276e73634ab65899a53fd4ba74 Mon Sep 17 00:00:00 2001 From: mcmoody <66175983+mcmoody@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:47:23 -0400 Subject: [PATCH 1048/1122] Update fn.md readability --- src/fn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn.md b/src/fn.md index 2402d56b8b..3516066d54 100644 --- a/src/fn.md +++ b/src/fn.md @@ -6,7 +6,7 @@ return type must be specified after an arrow `->`. The final expression in the function will be used as return value. Alternatively, the `return` statement can be used to return a value earlier -from within the function, even from inside loops or `if`s. +from within the function, even from inside loops or `if` statements. Let's rewrite FizzBuzz using functions! From 28dd0fa043f32b8945a0effc14cab2807ffdbf99 Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Sat, 20 Jun 2020 15:01:46 -0500 Subject: [PATCH 1049/1122] Update to mdbook 0.3.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b686a2f5d0..8c406cea16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: set -ex rustup --version rustc -Vv - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.5/mdbook-v0.3.5-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.7/mdbook-v0.3.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin mdbook --version rustup toolchain update nightly -c rust-docs script: From e515dc4447e86afe5c2bfdf8b179c455aba306eb Mon Sep 17 00:00:00 2001 From: Ross MacArthur Date: Tue, 23 Jun 2020 11:02:39 +0200 Subject: [PATCH 1050/1122] Remove mention of `try!` in `Display` example There is already a detailed explanation of what the `try!` macro is in `src/error/result/enter_question_mark.md` and it is confusing to introduce it here. --- src/hello/print/print_display/testcase_list.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/hello/print/print_display/testcase_list.md b/src/hello/print/print_display/testcase_list.md index 735b356952..63e400b6a0 100644 --- a/src/hello/print/print_display/testcase_list.md +++ b/src/hello/print/print_display/testcase_list.md @@ -13,14 +13,6 @@ Using `?` on `write!` looks like this: write!(f, "{}", value)?; ``` -Alternatively, you can also use the `try!` macro, which works the same way. -This is a bit more verbose and no longer recommended, but you may still see it in -older Rust code. Using `try!` looks like this: - -```rust,ignore -try!(write!(f, "{}", value)); -``` - With `?` available, implementing `fmt::Display` for a `Vec` is straightforward: @@ -42,7 +34,7 @@ impl fmt::Display for List { // count in `count`. for (count, v) in vec.iter().enumerate() { // For every element except the first, add a comma. - // Use the ? operator, or try!, to return on errors. + // Use the ? operator to return on errors. if count != 0 { write!(f, ", ")?; } write!(f, "{}", v)?; } From 4f01c6ba1fb2136cce6c76b89f28b0209a294c99 Mon Sep 17 00:00:00 2001 From: 16yuki0702 Date: Mon, 6 Jul 2020 11:48:51 +0900 Subject: [PATCH 1051/1122] Modify comments --- src/mod/use.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/use.md b/src/mod/use.md index 44cef988cc..8860bc20b4 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -44,10 +44,11 @@ fn main() { // This is equivalent to `use deeply::nested::function as function`. // This `function()` will shadow the outer one. use crate::deeply::nested::function; - function(); // `use` bindings have a local scope. In this case, the // shadowing of `function()` is only in this block. + function(); + println!("Leaving block"); } From e272a432c075113130f07767b301f0d19d89f540 Mon Sep 17 00:00:00 2001 From: 16yuki0702 Date: Tue, 14 Jul 2020 21:21:46 +0900 Subject: [PATCH 1052/1122] Modify supertraits sample code --- src/trait/supertraits.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trait/supertraits.md b/src/trait/supertraits.md index b1e10e10ed..5a735af1ae 100644 --- a/src/trait/supertraits.md +++ b/src/trait/supertraits.md @@ -26,9 +26,10 @@ trait CompSciStudent: Programmer + Student { fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String { format!( - "My name is {} and I attend {}. My Git username is {}", + "My name is {} and I attend {}. My favorite language is {}. My Git username is {}", student.name(), student.university(), + student.fav_language(), student.git_username() ) } From 9e09f7aeca9efce3e22a9b61571b4bde09f74651 Mon Sep 17 00:00:00 2001 From: dajamante Date: Sun, 26 Jul 2020 21:49:55 +0200 Subject: [PATCH 1053/1122] changed language to gender neutral --- src/error/option_unwrap.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md index 6269d5372a..df02b8c113 100644 --- a/src/error/option_unwrap.md +++ b/src/error/option_unwrap.md @@ -1,26 +1,26 @@ # `Option` & `unwrap` -In the last example, we showed that we can induce program failure at will. -We told our program to `panic` if the princess received an inappropriate -gift - a snake. But what if the princess expected a gift and didn't receive +In the last example, we showed that we can induce program failure at will. +We told our program to `panic` if the royal received an inappropriate +gift - a snake. But what if the royal expected a gift and didn't receive one? That case would be just as bad, so it needs to be handled! -We *could* test this against the null string (`""`) as we do with a snake. -Since we're using Rust, let's instead have the compiler point out cases +We *could* test this against the null string (`""`) as we do with a snake. +Since we're using Rust, let's instead have the compiler point out cases where there's no gift. -An `enum` called `Option` in the `std` library is used when absence is a +An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": * `Some(T)`: An element of type `T` was found * `None`: No element was found -These cases can either be explicitly handled via `match` or implicitly with +These cases can either be explicitly handled via `match` or implicitly with `unwrap`. Implicit handling will either return the inner element or `panic`. -Note that it's possible to manually customize `panic` with [expect][expect], -but `unwrap` otherwise leaves us with a less meaningful output than explicit -handling. In the following example, explicit handling yields a more +Note that it's possible to manually customize `panic` with [expect][expect], +but `unwrap` otherwise leaves us with a less meaningful output than explicit +handling. In the following example, explicit handling yields a more controlled result while retaining the option to `panic` if desired. ```rust,editable,ignore,mdbook-runnable @@ -35,9 +35,9 @@ fn give_commoner(gift: Option<&str>) { } } -// Our sheltered princess will `panic` at the sight of snakes. +// Our sheltered royal will `panic` at the sight of snakes. // All gifts are handled implicitly using `unwrap`. -fn give_princess(gift: Option<&str>) { +fn give_royal(gift: Option<&str>) { // `unwrap` returns a `panic` when it receives a `None`. let inside = gift.unwrap(); if inside == "snake" { panic!("AAAaaaaa!!!!"); } @@ -57,8 +57,8 @@ fn main() { let bird = Some("robin"); let nothing = None; - give_princess(bird); - give_princess(nothing); + give_royal(bird); + give_royal(nothing); } ``` From 13913223621fa2e9c1d53eb59bd7e79f948b3e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Justo=20Hern=C3=A1ndez=20Romera?= Date: Sat, 1 Aug 2020 18:26:40 +0200 Subject: [PATCH 1054/1122] Include Arc chapter. --- src/SUMMARY.md | 1 + src/std/arc.md | 27 +++++++++++++++++++++++++++ src/std/rc.md | 3 ++- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/std/arc.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7e00336d6b..093d3af8ee 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -182,6 +182,7 @@ - [Alternate/custom key types](std/hash/alt_key_types.md) - [HashSet](std/hash/hashset.md) - [`Rc`](std/rc.md) + - [`Arc`](std/arc.md) - [Std misc](std_misc.md) - [Threads](std_misc/threads.md) diff --git a/src/std/arc.md b/src/std/arc.md new file mode 100644 index 0000000000..566bd55eca --- /dev/null +++ b/src/std/arc.md @@ -0,0 +1,27 @@ +# Arc + +When shared ownership between threads is needed, `Arc`(Atomic Reference Counted) can be used. This struct, via the `Clone` implementation can create a reference pointer for the location of a value in the memory heap while increasing the reference counter. As it shares ownership between threads, when the last reference pointer to a value is out of scope, the variable is dropped. + +```rust,editable + +fn main() { +use std::sync::Arc; +use std::thread; + +// This variable declaration is where it's value is specified. +let apple = Arc::new("the same apple"); + +for _ in 0..10 { + // Here there is no value specification as it is a pointer to a reference + // in the memory heap. + let apple = Arc::clone(&apple); + + thread::spawn(move || { + // As Arc was used, threads can be spawned using the value allocated + // in the Arc variable pointer's location. + println!("{:?}", apple); + }); +} +} + +``` diff --git a/src/std/rc.md b/src/std/rc.md index 86e00e9081..0c3aef4b2d 100644 --- a/src/std/rc.md +++ b/src/std/rc.md @@ -48,7 +48,8 @@ fn main() { ### See also: -[std::rc][1] and [Arc][2]. +[std::rc][1] and [std::sync::arc][2]. [1]: https://doc.rust-lang.org/std/rc/index.html + [2]: https://doc.rust-lang.org/std/sync/struct.Arc.html From 957687f1649eb80e17a8595a3cad3a46134bc431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Justo=20Hern=C3=A1ndez=20Romera?= Date: Sat, 1 Aug 2020 18:28:52 +0200 Subject: [PATCH 1055/1122] Delete blank line in Rc chapter. --- src/std/rc.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/std/rc.md b/src/std/rc.md index 0c3aef4b2d..a9691b2448 100644 --- a/src/std/rc.md +++ b/src/std/rc.md @@ -51,5 +51,4 @@ fn main() { [std::rc][1] and [std::sync::arc][2]. [1]: https://doc.rust-lang.org/std/rc/index.html - [2]: https://doc.rust-lang.org/std/sync/struct.Arc.html From 9fd3b7e025fed1e6f5591408784c3c9a06c004fd Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 4 Aug 2020 18:58:06 -0700 Subject: [PATCH 1056/1122] Clarify wording --- src/testing/dev_dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testing/dev_dependencies.md b/src/testing/dev_dependencies.md index c20decfa63..3d4ccde556 100644 --- a/src/testing/dev_dependencies.md +++ b/src/testing/dev_dependencies.md @@ -1,7 +1,7 @@ # Development dependencies -Sometimes there is a need to have dependencies for tests (examples, -benchmarks) only. Such dependencies are added to `Cargo.toml` in the +Sometimes there is a need to have dependencies for tests (or examples, +or benchmarks) only. Such dependencies are added to `Cargo.toml` in the `[dev-dependencies]` section. These dependencies are not propagated to other packages which depend on this package. From 4961fa25c5a8104114e9695a3200b7e6ae766443 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sat, 8 Aug 2020 00:44:04 -0400 Subject: [PATCH 1057/1122] Add tuple `..` operator example --- .../match/destructuring/destructure_tuple.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/flow_control/match/destructuring/destructure_tuple.md b/src/flow_control/match/destructuring/destructure_tuple.md index 9d6260e433..30ae68f95c 100644 --- a/src/flow_control/match/destructuring/destructure_tuple.md +++ b/src/flow_control/match/destructuring/destructure_tuple.md @@ -4,15 +4,16 @@ Tuples can be destructured in a `match` as follows: ```rust,editable fn main() { - let pair = (0, -2); - // TODO ^ Try different values for `pair` + let triple = (0, -2, 3); + // TODO ^ Try different values for `triple` - println!("Tell me about {:?}", pair); + println!("Tell me about {:?}", triple); // Match can be used to destructure a tuple - match pair { - // Destructure the second - (0, y) => println!("First is `0` and `y` is `{:?}`", y), - (x, 0) => println!("`x` is `{:?}` and last is `0`", x), + match triple { + // Destructure the second and third elements + (0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z), + (1, ..) => println!("First is `1` and the rest doesn't matter"), + // `..` can be the used ignore the rest of the tuple _ => println!("It doesn't matter what they are"), // `_` means don't bind the value to a variable } From 7649cd70779b7474108add1f65d3da0448777567 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sat, 8 Aug 2020 22:34:19 -0400 Subject: [PATCH 1058/1122] Update extern crate related sections --- src/SUMMARY.md | 4 ++-- src/crates/lib.md | 2 +- src/crates/link.md | 29 ----------------------- src/crates/using_lib.md | 38 ++++++++++++++++++++++++++++++ src/mod/use.md | 2 +- src/testing/integration_testing.md | 8 +------ 6 files changed, 43 insertions(+), 40 deletions(-) delete mode 100644 src/crates/link.md create mode 100644 src/crates/using_lib.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 093d3af8ee..dfefcd5b90 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -82,8 +82,8 @@ - [File hierarchy](mod/split.md) - [Crates](crates.md) - - [Library](crates/lib.md) - - [`extern crate`](crates/link.md) + - [Creating a Library](crates/lib.md) + - [Using a Library](crates/using_lib.md) - [Cargo](cargo.md) - [Dependencies](cargo/deps.md) diff --git a/src/crates/lib.md b/src/crates/lib.md index 20b4cac59e..44593f3bb0 100644 --- a/src/crates/lib.md +++ b/src/crates/lib.md @@ -1,4 +1,4 @@ -# Library +# Creating a Library Let's create a library, and then see how to link it to another crate. diff --git a/src/crates/link.md b/src/crates/link.md deleted file mode 100644 index 828fbdbeba..0000000000 --- a/src/crates/link.md +++ /dev/null @@ -1,29 +0,0 @@ -# `extern crate` - -To link a crate to this new library, the `extern crate` declaration must be -used. This will not only link the library, but also import all its items under -a module named the same as the library. The visibility rules that apply to -modules also apply to libraries. - -```rust,ignore -// Link to `library`, import items under the `rary` module -extern crate rary; - -fn main() { - rary::public_function(); - - // Error! `private_function` is private - //rary::private_function(); - - rary::indirect_access(); -} -``` - -```txt -# Where library.rlib is the path to the compiled library, assumed that it's -# in the same directory here: -$ rustc executable.rs --extern rary=library.rlib && ./executable -called rary's `public_function()` -called rary's `indirect_access()`, that -> called rary's `private_function()` -``` diff --git a/src/crates/using_lib.md b/src/crates/using_lib.md new file mode 100644 index 0000000000..e04d321f7a --- /dev/null +++ b/src/crates/using_lib.md @@ -0,0 +1,38 @@ +# Using a Library + +To link a crate to this new library you may use `rustc`'s `--extern` flag. All +of its items will then be imported under a module named the same as the library. +This module generally behaves the same way as any other module. + +```rust,ignore +use rary::public_function; + +fn main() { + public_function(); + + // Error! `private_function` is private + //rary::private_function(); + + rary::indirect_access(); +} +``` + +```txt +# Where library.rlib is the path to the compiled library, assumed that it's +# in the same directory here: +$ rustc executable.rs --extern rary=library.rlib --edition=2018 && ./executable +called rary's `public_function()` +called rary's `indirect_access()`, that +> called rary's `private_function()` +``` + +## `extern crate` + +In rare cases, an explicit `extern crate` declaration is also required for older +Rust editions (2015 or earlier). It may also be required for certain libraries +such as `proc_macro` or `test` (which are shipped with `rustc`). +```rust,ignore +extern crate rary; +use rary::public_function; +// ... +``` diff --git a/src/mod/use.md b/src/mod/use.md index 8860bc20b4..365f297c13 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -4,7 +4,7 @@ The `use` declaration can be used to bind a full path to a new name, for easier access. It is often used like this: ```rust,editable,ignore -// extern crate deeply; // normally, this would exist and not be commented out! +// extern crate deeply; // May be required for Rust edition 2015 or earlier. use crate::deeply::nested::{ my_first_function, diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index 2ab0d85a6e..a4345ae945 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -10,7 +10,7 @@ Cargo looks for integration tests in `tests` directory next to `src`. File `src/lib.rs`: ```rust,ignore -// Assume that crate is called adder, will have to extern it in integration test. +// Define this in a crate called `adder`. pub fn add(a: i32, b: i32) -> i32 { a + b } @@ -19,9 +19,6 @@ pub fn add(a: i32, b: i32) -> i32 { File with test: `tests/integration_test.rs`: ```rust,ignore -// extern crate we're testing, same as any other code would do. -extern crate adder; - #[test] fn test_add() { assert_eq!(adder::add(3, 2), 5); @@ -66,9 +63,6 @@ pub fn setup() { File with test: `tests/integration_test.rs` ```rust,ignore -// extern crate we're testing, same as any other code will do. -extern crate adder; - // importing common module. mod common; From 2d288a30f131ea489ef890de452a7bbc3f902b51 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sat, 8 Aug 2020 23:36:31 -0400 Subject: [PATCH 1059/1122] remove reference in use.md --- src/mod/use.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/use.md b/src/mod/use.md index 365f297c13..7a57272b15 100644 --- a/src/mod/use.md +++ b/src/mod/use.md @@ -4,8 +4,6 @@ The `use` declaration can be used to bind a full path to a new name, for easier access. It is often used like this: ```rust,editable,ignore -// extern crate deeply; // May be required for Rust edition 2015 or earlier. - use crate::deeply::nested::{ my_first_function, my_second_function, From f2a98bab3228c532d83d757cda80b8305e8079f6 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sun, 9 Aug 2020 11:29:05 -0400 Subject: [PATCH 1060/1122] explicit use declaration --- src/crates/using_lib.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crates/using_lib.md b/src/crates/using_lib.md index e04d321f7a..ae8cc09635 100644 --- a/src/crates/using_lib.md +++ b/src/crates/using_lib.md @@ -5,10 +5,10 @@ of its items will then be imported under a module named the same as the library. This module generally behaves the same way as any other module. ```rust,ignore -use rary::public_function; +use rary; fn main() { - public_function(); + rary::public_function(); // Error! `private_function` is private //rary::private_function(); From d55f2a8a743174a7a737b9c1a1e934edbc328dc8 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sun, 9 Aug 2020 13:32:11 -0400 Subject: [PATCH 1061/1122] removed some explanations thats not quite right --- src/crates/using_lib.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/crates/using_lib.md b/src/crates/using_lib.md index ae8cc09635..102080700f 100644 --- a/src/crates/using_lib.md +++ b/src/crates/using_lib.md @@ -5,7 +5,7 @@ of its items will then be imported under a module named the same as the library. This module generally behaves the same way as any other module. ```rust,ignore -use rary; +// extern crate rary; // May be required for Rust 2015 edition or earlier fn main() { rary::public_function(); @@ -25,14 +25,3 @@ called rary's `public_function()` called rary's `indirect_access()`, that > called rary's `private_function()` ``` - -## `extern crate` - -In rare cases, an explicit `extern crate` declaration is also required for older -Rust editions (2015 or earlier). It may also be required for certain libraries -such as `proc_macro` or `test` (which are shipped with `rustc`). -```rust,ignore -extern crate rary; -use rary::public_function; -// ... -``` From 2434bfc257c5e2d75213e0311a828937b139933b Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sun, 9 Aug 2020 23:17:16 -0400 Subject: [PATCH 1062/1122] Split out variable shadowing example --- src/variable_bindings/scope.md | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/variable_bindings/scope.md b/src/variable_bindings/scope.md index d9639b42e3..c23db94485 100644 --- a/src/variable_bindings/scope.md +++ b/src/variable_bindings/scope.md @@ -1,9 +1,7 @@ # Scope and Shadowing Variable bindings have a scope, and are constrained to live in a *block*. A -block is a collection of statements enclosed by braces `{}`. Also, [variable -shadowing][variable-shadow] is allowed. - +block is a collection of statements enclosed by braces `{}`. ```rust,editable,ignore,mdbook-runnable fn main() { // This binding lives in the main function @@ -15,11 +13,6 @@ fn main() { let short_lived_binding = 2; println!("inner short: {}", short_lived_binding); - - // This binding *shadows* the outer one - let long_lived_binding = 5_f32; - - println!("inner long: {}", long_lived_binding); } // End of the block @@ -28,12 +21,23 @@ fn main() { // FIXME ^ Comment out this line println!("outer long: {}", long_lived_binding); - - // This binding also *shadows* the previous binding - let long_lived_binding = 'a'; - - println!("outer long: {}", long_lived_binding); } ``` +Also, a binding may have the same name as a binding from an outer block. This is +known as [variable shadowing][variable-shadow]. +```rust,editable,ignore,mdbook-runnable +fn main() { + let shadowed_binding = 1; + { + println!("before being shadowed: {}", shadowed_binding); + + // This binding *shadows* the outer one + let shadowed_binding = "a"; + + println!("after being shadowed: {}", shadowed_binding); + } + +} +``` [variable-shadow]: https://en.wikipedia.org/wiki/Variable_shadowing From ab1ba4f5bd241828891d51396313d9c2c524c2c2 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Sun, 9 Aug 2020 23:27:10 -0400 Subject: [PATCH 1063/1122] more prints --- src/variable_bindings/scope.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/variable_bindings/scope.md b/src/variable_bindings/scope.md index c23db94485..9e3c79e3ee 100644 --- a/src/variable_bindings/scope.md +++ b/src/variable_bindings/scope.md @@ -23,8 +23,7 @@ fn main() { println!("outer long: {}", long_lived_binding); } ``` -Also, a binding may have the same name as a binding from an outer block. This is -known as [variable shadowing][variable-shadow]. +Also, [variable shadowing][variable-shadow] is allowed. ```rust,editable,ignore,mdbook-runnable fn main() { let shadowed_binding = 1; @@ -33,11 +32,15 @@ fn main() { println!("before being shadowed: {}", shadowed_binding); // This binding *shadows* the outer one - let shadowed_binding = "a"; + let shadowed_binding = "abc"; - println!("after being shadowed: {}", shadowed_binding); + println!("shadowed in inner block: {}", shadowed_binding); } + println!("outside inner block: {}", shadowed_binding); + // This binding *shadows* the previous binding + let shadowed_binding = 2; + println!("shadowed in outer block: {}", shadowed_binding); } ``` [variable-shadow]: https://en.wikipedia.org/wiki/Variable_shadowing From f245c1ce487c56e8f3a7dfa8d1ba81da696139cf Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 18 Aug 2020 07:44:11 -0700 Subject: [PATCH 1064/1122] prefer `length` over `size` when talking about number of elements vs. bytesize These terms can be synonyms, so what's there isn't wrong, but `length` is a less loaded term. e.g. the example: [T; size] _might_ be misconstrued as: ``` // two float32's has a size of 8 bytes let my_array: [float32; 8] = [1.0, 2.0]; // wrong ``` --- src/primitives/array.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/primitives/array.md b/src/primitives/array.md index f612c1dbc2..50ea52fca4 100644 --- a/src/primitives/array.md +++ b/src/primitives/array.md @@ -1,10 +1,10 @@ # Arrays and Slices An array is a collection of objects of the same type `T`, stored in contiguous -memory. Arrays are created using brackets `[]`, and their size, which is known -at compile time, is part of their type signature `[T; size]`. +memory. Arrays are created using brackets `[]`, and their length, which is known +at compile time, is part of their type signature `[T; length]`. -Slices are similar to arrays, but their size is not known at compile time. +Slices are similar to arrays, but their length is not known at compile time. Instead, a slice is a two-word object, the first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture eg 64 bits on an x86-64. @@ -31,8 +31,8 @@ fn main() { println!("first element of the array: {}", xs[0]); println!("second element of the array: {}", xs[1]); - // `len` returns the size of the array - println!("array size: {}", xs.len()); + // `len` returns the count of elements in the array + println!("number of elements in array: {}", xs.len()); // Arrays are stack allocated println!("array occupies {} bytes", mem::size_of_val(&xs)); From 95061044532f7ee105926af1beba04ca1ced4a77 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Wed, 26 Aug 2020 19:29:29 -0700 Subject: [PATCH 1065/1122] Prevent duplicated error information in "wrapping errors" example The "Wrapping errors" example, which illustrates how to wrap errors, is using the wrapped error in the text that is displayed as well as the implementation of source(). In so doing it effectively duplicates the error information. Such behavior does not play nice with error reporting crates such as anyhow, eyre, and others that make use of both this data. It is also questionable at best from a logical point of view, because, as the name suggests, the source should be a lower level error that is the cause of this one. With this change we update the documentation, suggesting the usage of a custom error string describing at a higher level what went wrong. To keep the example simple, we did not include the actual string in the error (a comment already suggests that this could be done), although that probably should be done in real life to provide additional context. An alternative approach would be to not return a source, but I figured that it's sort of desired for the illustration of wrapping an error. --- src/error/multiple_error_types/wrap_error.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/error/multiple_error_types/wrap_error.md b/src/error/multiple_error_types/wrap_error.md index e8acd25197..392b783aed 100644 --- a/src/error/multiple_error_types/wrap_error.md +++ b/src/error/multiple_error_types/wrap_error.md @@ -4,6 +4,7 @@ An alternative to boxing errors is to wrap them in your own error type. ```rust,editable use std::error; +use std::error::Error as _; use std::num::ParseIntError; use std::fmt; @@ -22,8 +23,10 @@ impl fmt::Display for DoubleError { match *self { DoubleError::EmptyVec => write!(f, "please use a vector with at least one element"), - // This is a wrapper, so defer to the underlying types' implementation of `fmt`. - DoubleError::Parse(ref e) => e.fmt(f), + // The wrapped error contains additional information and is available + // via the source() method. + DoubleError::Parse(..) => + write!(f, "the provided string could not be parsed as int"), } } } @@ -51,6 +54,8 @@ impl From for DoubleError { fn double_first(vec: Vec<&str>) -> Result { let first = vec.first().ok_or(DoubleError::EmptyVec)?; + // Here we implicitly use the `ParseIntError` implementation of `From` (which + // we defined above) in order to create a `DoubleError`. let parsed = first.parse::()?; Ok(2 * parsed) @@ -59,7 +64,12 @@ fn double_first(vec: Vec<&str>) -> Result { fn print(result: Result) { match result { Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {}", e), + Err(e) => { + println!("Error: {}", e); + if let Some(source) = e.source() { + println!(" Caused by: {}", source); + } + }, } } From a025bdf5b768310912c072aac85b35ecadd0c6c0 Mon Sep 17 00:00:00 2001 From: Xiaochuan Yu Date: Tue, 1 Sep 2020 21:12:58 -0400 Subject: [PATCH 1066/1122] Remove lifetime annotation from struct example --- src/custom_types/structs.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index b7f84c2fa4..97bd46ba2a 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -9,9 +9,8 @@ There are three types of structures ("structs") that can be created using the ```rust,editable #[derive(Debug)] -struct Person<'a> { - // The 'a defines a lifetime - name: &'a str, +struct Person { + name: String, age: u8, } @@ -38,7 +37,7 @@ struct Rectangle { fn main() { // Create struct with field init shorthand - let name = "Peter"; + let name = String::from("Peter"); let age = 27; let peter = Person { name, age }; @@ -93,9 +92,8 @@ fn main() { ### See also: -[`attributes`][attributes], [lifetime][lifetime] and [destructuring][destructuring] +[`attributes`][attributes], and [destructuring][destructuring] [attributes]: ../attribute.md [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language) [destructuring]: ../flow_control/match/destructuring.md -[lifetime]: ../scope/lifetime.md From 6450eee2ce861f24542877b6a7f0308b1bc4a52a Mon Sep 17 00:00:00 2001 From: ak4ra <45451374+ak4ra@users.noreply.github.com> Date: Fri, 4 Sep 2020 15:59:37 +0300 Subject: [PATCH 1067/1122] Clone.md comment and variable name change If I understand this correctly, moved_pair is not a copy, as Pair does not implement Copy, it is a move. Perhaps 'copy' is used in the comment and name because of the similar example in lines 22-23 above, where there is an actual copy. --- src/trait/clone.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trait/clone.md b/src/trait/clone.md index 1b9d953b71..5d6747a47b 100644 --- a/src/trait/clone.md +++ b/src/trait/clone.md @@ -30,9 +30,9 @@ fn main() { let pair = Pair(Box::new(1), Box::new(2)); println!("original: {:?}", pair); - // Copy `pair` into `moved_pair`, moves resources + // Move `pair` into `moved_pair`, moves resources let moved_pair = pair; - println!("copy: {:?}", moved_pair); + println!("moved: {:?}", moved_pair); // Error! `pair` has lost its resources //println!("original: {:?}", pair); From afad5bc8250bbfb0cac2694fbe13fd736190b864 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sat, 5 Sep 2020 21:49:44 +0200 Subject: [PATCH 1068/1122] Replace panic example with a simpler version --- src/error/panic.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/error/panic.md b/src/error/panic.md index a690642539..5524dbf6f2 100644 --- a/src/error/panic.md +++ b/src/error/panic.md @@ -1,19 +1,19 @@ # `panic` -The simplest error handling mechanism we will see is `panic`. It prints an -error message, starts unwinding the stack, and usually exits the program. -Here, we explicitly call `panic` on our error condition: +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the stack, and usually exits the program. +Here, we explicitly call `panic` on our error condition: ```rust,editable,ignore,mdbook-runnable -fn give_princess(gift: &str) { - // Princesses hate snakes, so we need to stop if she disapproves! - if gift == "snake" { panic!("AAAaaaaa!!!!"); } +fn drink(beverage: &str) { + // You shouldn't drink too much sugary beverages. + if beverage == "lemonade" { panic!("AAAaaaaa!!!!"); } - println!("I love {}s!!!!!", gift); + println!("Some refreshing {} is all I need.", beverage); } fn main() { - give_princess("teddy bear"); - give_princess("snake"); + drink("water"); + drink("lemonade"); } ``` From 363499a5769e6820b11e29f2a75d4954fae352ec Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Mon, 28 Sep 2020 20:32:31 +0200 Subject: [PATCH 1069/1122] Prefer `const` over `static` --- src/std_misc/threads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_misc/threads.md b/src/std_misc/threads.md index 7a9b2cf22d..2f37d1c4a3 100644 --- a/src/std_misc/threads.md +++ b/src/std_misc/threads.md @@ -6,7 +6,7 @@ function, the argument of this function is a moving closure. ```rust,editable use std::thread; -static NTHREADS: i32 = 10; +const NTHREADS: u32 = 10; // This is the `main` thread fn main() { From 77be419fdec91074b2ecd86ebf531f12a0b892a4 Mon Sep 17 00:00:00 2001 From: Lalit Shankar Chowdhury Date: Sat, 3 Oct 2020 12:32:57 +0530 Subject: [PATCH 1070/1122] Update README.md Corrected a verb form --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2ac7c65ce..29fbd75413 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Rust by Example by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. +dually licensed as above, without any additional terms or conditions. From 2ed758e77d4256799d84cf0caba8910c8a51100c Mon Sep 17 00:00:00 2001 From: Bruno Kirschner Date: Sat, 3 Oct 2020 15:45:50 +0200 Subject: [PATCH 1071/1122] Add missing main function in static life time example. --- src/scope/lifetime/static_lifetime.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index 7a1bddfa0f..c9a9d095c8 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -75,13 +75,11 @@ does not: ```rust,editable,compile_fail use std::fmt::Debug; -fn print_it( input: impl Debug + 'static ) -{ +fn print_it( input: impl Debug + 'static ) { println!( "'static value passed in is: {:?}", input ); } -fn use_it() -{ +fn main() { // i is owned and contains no references, thus it's 'static: let i = 5; print_it(i); From a6708bf4b7c0732e192afdf80e08c796775aba66 Mon Sep 17 00:00:00 2001 From: sakex Date: Fri, 9 Oct 2020 01:02:47 +0200 Subject: [PATCH 1072/1122] Add 1.45.0 cast documentation --- src/types/cast.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/types/cast.md b/src/types/cast.md index 7d990976a3..16e4521868 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -59,5 +59,25 @@ fn main() { println!("1000 as a u8 is : {}", 1000 as u8); // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); + + // Since Rust 1.45, the `as` keyword performs a *saturating cast* when casting from float to int. + // If the floating point value exceeds the upper bound or is less than the lower bound, the returned value will be equal to the bound crossed. + + // 300.0 is 255 + println!("300.0 is {}", 300.0_f32 as u8); + // -100.0 as u8 is 0 + println!("-100.0 as u8 is {}", -100.0_f32 as u8); + // nan as u8 is 0 + println!("nan as u8 is {}", f32::NAN as u8); + + // This behavior incures a small runtime cost and can be avoided with unsafe methods: + unsafe { + // 300.0 is 44 + println!("300.0 is {}", 300.0_f32.to_int_unchecked::()); + // -100.0 as u8 is 156 + println!("-100.0 as u8 is {}", (-100.0_f32).to_int_unchecked::()); + // nan as u8 is 0 + println!("nan as u8 is {}", f32::NAN.to_int_unchecked::()); + } } ``` From 13317575a3ae9ae5605cfff7c134e7ed596426ce Mon Sep 17 00:00:00 2001 From: sakex Date: Fri, 9 Oct 2020 01:07:45 +0200 Subject: [PATCH 1073/1122] Add warning for unsafe methods --- src/types/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/cast.md b/src/types/cast.md index 16e4521868..2ca18c1784 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -70,7 +70,7 @@ fn main() { // nan as u8 is 0 println!("nan as u8 is {}", f32::NAN as u8); - // This behavior incures a small runtime cost and can be avoided with unsafe methods: + // This behavior incures a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: unsafe { // 300.0 is 44 println!("300.0 is {}", 300.0_f32.to_int_unchecked::()); From a4227276bb688854501fee3cde50203414e41103 Mon Sep 17 00:00:00 2001 From: Amjad Alsharafi Date: Sat, 29 Aug 2020 17:50:22 +0800 Subject: [PATCH 1074/1122] Add partial moves example --- src/SUMMARY.md | 1 + src/scope/move/partial_move.md | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/scope/move/partial_move.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index dfefcd5b90..216bceadfe 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -116,6 +116,7 @@ - [RAII](scope/raii.md) - [Ownership and moves](scope/move.md) - [Mutability](scope/move/mut.md) + - [Partial moves](scope/move/partial_move.md) - [Borrowing](scope/borrow.md) - [Mutability](scope/borrow/mut.md) - [Aliasing](scope/borrow/alias.md) diff --git a/src/scope/move/partial_move.md b/src/scope/move/partial_move.md new file mode 100644 index 0000000000..7afa7e5419 --- /dev/null +++ b/src/scope/move/partial_move.md @@ -0,0 +1,40 @@ +# Partial moves + +Pattern bindings can have `by-move` and `by-reference` bindings at +the same time which is used in [destructuring]. Using these pattern +will result in partial move for the variable, which means that part +of the variable is moved while other parts stayed. In this case, the +parent variable cannot be used afterwards as a whole. However, parts +of it that are referenced and not moved can be used. + +```rust,editable +fn main() { + #[derive(Debug)] + struct Person { + name: String, + age: u8, + } + + let person = Person { + name: String::from("Alice"), + age: 20, + }; + + // `name` is moved out of person, but `age` is referenced + let Person { name, ref age } = person; + + println!("The person's age is {}", age); + + println!("The person's name is {}", name); + + // Error! borrow of partially moved value: `person` partial move occurs + //println!("The person struct is {:?}", person); + + // `person` cannot be used but `person.age` can be used as it is not moved + println!("The person's age from person struct is {}", person.age); +} +``` +### See also: +[destructuring][destructuring] + +[destructuring]: ../../flow_control/match/destructuring.md \ No newline at end of file From c60a81bf0b65cce0c3c7f3adf5120ab813dd55bd Mon Sep 17 00:00:00 2001 From: 16yuki0702 Date: Wed, 21 Oct 2020 23:07:58 +0900 Subject: [PATCH 1075/1122] Formatting footer items. some footers have different format. this PR corrects them. --- src/hello/print/print_debug.md | 2 +- src/hello/print/print_display.md | 4 ++-- src/primitives.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index 9f65460768..e9f043d93d 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -74,7 +74,7 @@ One can manually implement `fmt::Display` to control the display. ### See also: -[attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], +[`attributes`][attributes], [`derive`][derive], [`std::fmt`][fmt], and [`struct`][structs] [attributes]: https://doc.rust-lang.org/reference/attributes.html diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 2083a5f643..1ff31f27ac 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -118,8 +118,8 @@ Debug: Complex { real: 3.3, imag: 7.2 } ### See also: -[`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], -[`trait`][traits], and [use][use] +[`derive`][derive], [`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], +[`trait`][traits], and [`use`][use] [derive]: ../../trait/derive.md [fmt]: https://doc.rust-lang.org/std/fmt/ diff --git a/src/primitives.md b/src/primitives.md index dfa75068bc..6b579e5eaf 100644 --- a/src/primitives.md +++ b/src/primitives.md @@ -55,7 +55,7 @@ fn main() { ### See also: -[the `std` library][std], [`mut`][mut], [inference], and [shadowing] +[the `std` library][std], [`mut`][mut], [`inference`][inference], and [`shadowing`][shadowing] [std]: https://doc.rust-lang.org/std/ [mut]: variable_bindings/mut.md From 1886fda6981b723e4de637074455558f8bc1e83c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 28 Oct 2020 13:46:54 -0500 Subject: [PATCH 1076/1122] Remove incorrect "lambda" terminology We only use "closures" to describe this construct. --- src/fn/closures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fn/closures.md b/src/fn/closures.md index a26cb2089c..baf1c422c1 100644 --- a/src/fn/closures.md +++ b/src/fn/closures.md @@ -1,8 +1,8 @@ # Closures -Closures in Rust, also called lambda expressions or lambdas, are functions that can capture -the enclosing environment. For example, a closure that captures the x -variable: +Closures are functions that can capture the enclosing environment. For +example, a closure that captures the x variable: + ```Rust |val| val + x ``` From c285c2750652fa00db6e21599fef835234314bcc Mon Sep 17 00:00:00 2001 From: Next Turn <45985406+NextTurn@users.noreply.github.com> Date: Sun, 15 Nov 2020 12:51:12 +0800 Subject: [PATCH 1077/1122] Minor grammar suggestion --- src/hello/print/print_debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_debug.md b/src/hello/print/print_debug.md index e9f043d93d..161b0b7729 100644 --- a/src/hello/print/print_debug.md +++ b/src/hello/print/print_debug.md @@ -20,7 +20,7 @@ struct UnPrintable(i32); struct DebugPrintable(i32); ``` -All `std` library types automatically are printable with `{:?}` too: +All `std` library types are automatically printable with `{:?}` too: ```rust,editable // Derive the `fmt::Debug` implementation for `Structure`. `Structure` From 501e627fbad4b34b2d6ff23872778470c26b59a1 Mon Sep 17 00:00:00 2001 From: Nix Date: Fri, 27 Nov 2020 13:37:36 +0900 Subject: [PATCH 1078/1122] Fix some markdown lint warnings On README.md, CODE_OF_CONDUCT.md and CONTRIBUTING.md --- CODE_OF_CONDUCT.md | 3 +-- CONTRIBUTING.md | 1 - README.md | 10 +++++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index d70b2b52ac..cdfd7cfe80 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -11,13 +11,12 @@ A version of this document [can be found online](https://www.rust-lang.org/condu * Please be kind and courteous. There's no need to be mean or rude. * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. * Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. * Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. ## Moderation - These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team]. 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70d908f0bc..665a708c03 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,6 @@ If you make additions or other changes to a pull request, feel free to either am previous commits or only add new ones, however you prefer. We may ask you to squash your commits before merging, depending. - ## Issue Tracker You can find the issue tracker [on diff --git a/README.md b/README.md index a2ac7c65ce..a889c6a131 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Learn Rust with examples (Live code editor included) ## Using -If you'd like to read Rust by Example, you can visit https://doc.rust-lang.org/rust-by-example/ +If you'd like to read Rust by Example, you can visit to read it online. If you'd like to read it locally, [install Rust], and then: @@ -44,10 +44,10 @@ Please see the [CONTRIBUTING.md] file for more details. Rust by Example is licensed under either of - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) +* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + ) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or + ) at your option. From 0a360903c149adc54342766dff806b3469aff6dc Mon Sep 17 00:00:00 2001 From: Rafael Cintra Date: Fri, 27 Nov 2020 15:47:53 +1000 Subject: [PATCH 1079/1122] Moved "See also" link to the correct page. The "8.5.1.3. pointers/ref" code example contains multiple usages of the ref pattern, however no link to it is included in the "See also" section at the end of the page (the section is missing). In the next page, "8.5.1.4. structs", the code example contains no usage of the ref pattern, however its "See also" section contains a link to it. This commit moves the ref pattern link to the previous page: "8.5.1.3. pointers/ref" to remedy the problem. --- src/flow_control/match/destructuring/destructure_pointers.md | 4 ++++ .../match/destructuring/destructure_structures.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/flow_control/match/destructuring/destructure_pointers.md b/src/flow_control/match/destructuring/destructure_pointers.md index d92ba22be8..43ca3bd281 100644 --- a/src/flow_control/match/destructuring/destructure_pointers.md +++ b/src/flow_control/match/destructuring/destructure_pointers.md @@ -59,3 +59,7 @@ fn main() { } } ``` + +### See also: + +[The ref pattern](../../../scope/borrow/ref.md) diff --git a/src/flow_control/match/destructuring/destructure_structures.md b/src/flow_control/match/destructuring/destructure_structures.md index 135b33cc19..9e43b70c15 100644 --- a/src/flow_control/match/destructuring/destructure_structures.md +++ b/src/flow_control/match/destructuring/destructure_structures.md @@ -29,4 +29,4 @@ fn main() { ### See also: -[Structs](../../../custom_types/structs.md), [The ref pattern](../../../scope/borrow/ref.md) +[Structs](../../../custom_types/structs.md) From 4d8d99bf84beb87c7ef10137c46220702040be70 Mon Sep 17 00:00:00 2001 From: Nix Date: Fri, 27 Nov 2020 17:14:33 +0900 Subject: [PATCH 1080/1122] Fix markdown lint and line wrap in structs.md --- src/custom_types/structs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 97bd46ba2a..0dfc261292 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -88,9 +88,11 @@ fn main() { 1. Add a function `rect_area` which calculates the area of a rectangle (try using nested destructuring). -2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`. +2. Add a function `square` which takes a `Point` and a `f32` as arguments, and + returns a `Rectangle` with its lower left corner on the point, and a width and + height corresponding to the `f32`. -### See also: +### See also [`attributes`][attributes], and [destructuring][destructuring] From 48aced1b66e770c2fb1999d104f84b9e5acd2a3e Mon Sep 17 00:00:00 2001 From: Ejez <48388358+ejez@users.noreply.github.com> Date: Sun, 29 Nov 2020 17:53:02 +0300 Subject: [PATCH 1081/1122] Update old invalid link Update old invalid link in src/error/option_unwrap/map.md --- src/error/option_unwrap/map.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error/option_unwrap/map.md b/src/error/option_unwrap/map.md index c458e7d955..6682e317a9 100644 --- a/src/error/option_unwrap/map.md +++ b/src/error/option_unwrap/map.md @@ -80,7 +80,7 @@ fn main() { [closures][closures], [`Option`][option], [`Option::map()`][map] -[combinators]: https://doc.rust-lang.org/book/glossary.html#combinators +[combinators]: https://doc.rust-lang.org/reference/glossary.html#combinator [closures]: ../../fn/closures.md [option]: https://doc.rust-lang.org/std/option/enum.Option.html [map]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map From de579546dd9bd82c79a8a1f9ebfc43144f10a5a0 Mon Sep 17 00:00:00 2001 From: falc0n9 Date: Tue, 1 Dec 2020 20:14:10 +0100 Subject: [PATCH 1082/1122] Drop extern crate --- src/cargo/deps.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cargo/deps.md b/src/cargo/deps.md index 7403a2ae76..8913e9e383 100644 --- a/src/cargo/deps.md +++ b/src/cargo/deps.md @@ -56,8 +56,7 @@ lots of great packages on [crates.io](https://crates.io) (the official Rust package registry). One popular choice is [clap](https://crates.io/crates/clap). As of this writing, the most recent published version of `clap` is `2.27.1`. To add a dependency to our program, we can simply add the following to our -`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`. And of course, `extern -crate clap` in `main.rs`, just like normal. And that's it! You can start using +`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`. And that's it! You can start using `clap` in your program. `cargo` also supports [other types of dependencies][dependencies]. Here is just From e81de8f24084a70cb967589341101517c632c349 Mon Sep 17 00:00:00 2001 From: shreepads Date: Sun, 6 Dec 2020 13:42:00 +0530 Subject: [PATCH 1083/1122] Clarify distinction between for iter and into_iter The existing code examples for `for iter` and `for into_iter` don't make the distinction very clear to the user. Although this is explained at the end, allowing the user experiment with the match types and showing how the collection gets consumed in `into_iter` but not in `iter` would help them understand better. --- src/flow_control/for.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 99e6458493..1e9191498d 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -67,9 +67,12 @@ fn main() { for name in names.iter() { match name { &"Ferris" => println!("There is a rustacean among us!"), + // TODO ^ Try deleting the & and matching just "Ferris" _ => println!("Hello {}", name), } } + + println!("names: {:?}", names); } ``` @@ -87,6 +90,9 @@ fn main() { _ => println!("Hello {}", name), } } + + println!("names: {:?}", names); + // FIXME ^ Comment out this line } ``` From 4cc85655b97be83acbca5d036cf679f39ea66eb8 Mon Sep 17 00:00:00 2001 From: shreepads Date: Sun, 6 Dec 2020 14:01:01 +0530 Subject: [PATCH 1084/1122] Fix for.md to ignore compiler error for FIXME The user needs to fix the section by commenting out `println!("names: {:?}", names);` before running the example --- src/flow_control/for.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 1e9191498d..23445fe4fd 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -80,7 +80,7 @@ fn main() { data is provided. Once the collection has been consumed it is no longer available for reuse as it has been 'moved' within the loop. -```rust, editable +```rust, editable, ignore fn main() { let names = vec!["Bob", "Frank", "Ferris"]; From 6dc57f42be6977d8b805af864d75c45969dd95ae Mon Sep 17 00:00:00 2001 From: shreepads Date: Sun, 6 Dec 2020 14:25:30 +0530 Subject: [PATCH 1085/1122] Clarify first matching arm and all possible values The point that the first matching arm is evaluated must be made in the text. Prompt the user to add `13` to the list of primes to demonstrate this in action. The importance of the catch-all expression `_` would be more clear once the user tries commenting it out. --- src/flow_control/match.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/flow_control/match.md b/src/flow_control/match.md index 02a80670ff..6beeea3668 100644 --- a/src/flow_control/match.md +++ b/src/flow_control/match.md @@ -1,7 +1,8 @@ # match Rust provides pattern matching via the `match` keyword, which can be used like -a C `switch`. +a C `switch`. The first matching arm is evaluated and all possible values must be +covered. ```rust,editable fn main() { @@ -14,10 +15,12 @@ fn main() { 1 => println!("One!"), // Match several values 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), + // TODO ^ Try adding 13 to the list of prime values // Match an inclusive range 13..=19 => println!("A teen"), // Handle the rest of cases _ => println!("Ain't special"), + // TODO ^ Try commenting out this catch-all arm } let boolean = true; From 9a81505a26f199e7d8b0f21c6cd56a4211c2e6b1 Mon Sep 17 00:00:00 2001 From: ppenguin Date: Tue, 15 Dec 2020 18:47:07 +0800 Subject: [PATCH 1086/1122] Simplify the call of filter_map --- src/error/iter_result.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/error/iter_result.md b/src/error/iter_result.md index cef97ae212..3b03090d5d 100644 --- a/src/error/iter_result.md +++ b/src/error/iter_result.md @@ -24,8 +24,7 @@ fn main() { let strings = vec!["tofu", "93", "18"]; let numbers: Vec<_> = strings .into_iter() - .map(|s| s.parse::()) - .filter_map(Result::ok) + .filter_map(|s| s.parse::().ok()) .collect(); println!("Results: {:?}", numbers); } From 31fb78bc929a2d2cecf673344596587ff18be81b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 22 Dec 2020 01:13:26 +0800 Subject: [PATCH 1087/1122] Add description for book.toml `book.description` value in book.toml provides nice HTML document metadata. Ref: https://github.com/rust-lang/mdBook/blob/8e673c9/src/theme/index.hbs#L12 --- book.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book.toml b/book.toml index 45ae5fd944..089d703286 100644 --- a/book.toml +++ b/book.toml @@ -1,6 +1,6 @@ [book] title = "Rust By Example" -description = "A description" +description = "Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries." author = "The Rust Community" [output.html.playpen] From 9b02990b8c3f5b9ecbe82d195e23d2522b898c23 Mon Sep 17 00:00:00 2001 From: Mark Saward Date: Sun, 3 Jan 2021 17:43:16 +1100 Subject: [PATCH 1088/1122] Add note for match guards to include catch-all The compiler doesn't check for conditions being exhausted when using arbitrary expressions (#74277). This adds a note with example specifying that you need to cover all remaining conditions with `_`. My only concern is that my example may encourage people to use match guards as I did there, instead of something like: ```rust match number { 0 => println!("Zero"), 1..=u8::MAX => println!("Greater than zero"), } ``` --- src/flow_control/match/guard.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/flow_control/match/guard.md b/src/flow_control/match/guard.md index 336b7f1233..9caa65aa00 100644 --- a/src/flow_control/match/guard.md +++ b/src/flow_control/match/guard.md @@ -18,6 +18,22 @@ fn main() { } ``` +Note that the compiler does not check arbitrary expressions for whether all +possible conditions have been checked. Therefore, you must use the `_` pattern +at the end. + +```rust,editable +fn main() { + let number: u8 = 4; + + match number { + i if i == 0 => println!("Zero"), + i if i > 0 => println!("Greater than zero"), + _ => println!("Fell through"), // This should not be possible to reach + } +} +``` + ### See also: [Tuples](../../primitives/tuples.md) From f51daeefa4c900bfc8c6b103672efbb05c69c574 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 5 Jan 2021 20:37:39 +0800 Subject: [PATCH 1089/1122] Update mdbook - Changelog to 0.4.5: https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-045) - mdbook security advisory: https://blog.rust-lang.org/2021/01/04/mdbook-security-advisory.html Some breaking changes were introduced in 0.4.0 but I skimmed RBD built by 0.4.5 and no regression detected. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8c406cea16..17adda5b9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: set -ex rustup --version rustc -Vv - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.7/mdbook-v0.3.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.5/mdbook-v0.4.5-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin mdbook --version rustup toolchain update nightly -c rust-docs script: From 4ff2dd8070c7843d9909df02577b3e1886c5bc31 Mon Sep 17 00:00:00 2001 From: ppenguin Date: Sat, 9 Jan 2021 11:08:27 +0800 Subject: [PATCH 1090/1122] Replace for loop with iteration --- src/std_misc/threads/testcase_mapreduce.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/std_misc/threads/testcase_mapreduce.md b/src/std_misc/threads/testcase_mapreduce.md index 9efc34a87f..641dc227cd 100644 --- a/src/std_misc/threads/testcase_mapreduce.md +++ b/src/std_misc/threads/testcase_mapreduce.md @@ -103,21 +103,13 @@ fn main() { * Collect our intermediate results, and combine them into a final result ************************************************************************/ - // collect each thread's intermediate results into a new Vec - let mut intermediate_sums = vec![]; - for child in children { - // collect each child thread's return-value - let intermediate_sum = child.join().unwrap(); - intermediate_sums.push(intermediate_sum); - } - - // combine all intermediate sums into a single final sum. + // combine each thread's intermediate results into a single final sum. // // we use the "turbofish" ::<> to provide sum() with a type hint. // // TODO: try without the turbofish, by instead explicitly // specifying the type of final_result - let final_result = intermediate_sums.iter().sum::(); + let final_result = children.into_iter().map(|c| c.join().unwrap()).sum::(); println!("Final sum result: {}", final_result); } From 49c84a1c32ec6a009ad2bd3f109a148dd022bb0d Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Wed, 13 Jan 2021 15:54:54 -0800 Subject: [PATCH 1091/1122] Fixed styling on closure example --- src/fn/closures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fn/closures.md b/src/fn/closures.md index baf1c422c1..68bfd8adf6 100644 --- a/src/fn/closures.md +++ b/src/fn/closures.md @@ -7,9 +7,9 @@ example, a closure that captures the x variable: |val| val + x ``` -The syntax and capabilities of closures make them very convenient for +The syntax and capabilities of closures make them very convenient for on the fly usage. Calling a closure is exactly like calling a function. -However, both input and return types *can* be inferred and input +However, both input and return types *can* be inferred and input variable names *must* be specified. Other characteristics of closures include: @@ -20,7 +20,7 @@ Other characteristics of closures include: ```rust,editable fn main() { // Increment via closures and functions. - fn function (i: i32) -> i32 { i + 1 } + fn function(i: i32) -> i32 { i + 1 } // Closures are anonymous, here we are binding them to references // Annotation is identical to function annotation but is optional From 2996832b89e435c91d9756be7045bdad981a520a Mon Sep 17 00:00:00 2001 From: Claudio Noguera Date: Tue, 26 Jan 2021 18:16:34 +0100 Subject: [PATCH 1092/1122] Update arc.md Fix typo, remove apostrophe --- src/std/arc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/arc.md b/src/std/arc.md index 566bd55eca..d36ca0802a 100644 --- a/src/std/arc.md +++ b/src/std/arc.md @@ -8,7 +8,7 @@ fn main() { use std::sync::Arc; use std::thread; -// This variable declaration is where it's value is specified. +// This variable declaration is where its value is specified. let apple = Arc::new("the same apple"); for _ in 0..10 { From aa04f92c8aea81936159e7e97b53a89e8eb12ae6 Mon Sep 17 00:00:00 2001 From: wangao Date: Sun, 31 Jan 2021 17:12:11 +0800 Subject: [PATCH 1093/1122] doc(testcase_linked_list): add a little extra note about pattern Add a little extra note about pattern after rust 2018 edition --- src/custom_types/enum/testcase_linked_list.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/custom_types/enum/testcase_linked_list.md b/src/custom_types/enum/testcase_linked_list.md index 84855d1c54..b07adecf6b 100644 --- a/src/custom_types/enum/testcase_linked_list.md +++ b/src/custom_types/enum/testcase_linked_list.md @@ -32,6 +32,9 @@ impl List { // depends on the variant of `self` // `self` has type `&List`, and `*self` has type `List`, matching on a // concrete type `T` is preferred over a match on a reference `&T` + // after Rust 2018 you can use self here and tail (with no ref) below as well, + // rust will infer &s and ref tail. + // See https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/default-match-bindings.html match *self { // Can't take ownership of the tail, because `self` is borrowed; // instead take a reference to the tail From c6514df999094bf257e7999bbabd93ad6fce7d8d Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 3 Feb 2021 11:57:13 -0800 Subject: [PATCH 1094/1122] remove // --- src/scope/lifetime/explicit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/lifetime/explicit.md b/src/scope/lifetime/explicit.md index ebd7b69017..f0ecdf5fca 100644 --- a/src/scope/lifetime/explicit.md +++ b/src/scope/lifetime/explicit.md @@ -40,7 +40,7 @@ fn failed_borrow<'a>() { let _x = 12; // ERROR: `_x` does not live long enough - //let y: &'a i32 = &_x; + let y: &'a i32 = &_x; // Attempting to use the lifetime `'a` as an explicit type annotation // inside the function will fail because the lifetime of `&_x` is shorter // than that of `y`. A short lifetime cannot be coerced into a longer one. From 6cfac4744bcf3c504d83bac561732a18a9501917 Mon Sep 17 00:00:00 2001 From: hsi <53867065+username@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:19:35 +0100 Subject: [PATCH 1095/1122] Fix link of formatting traits --- src/hello/print/print_display.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 1ff31f27ac..4d27650e16 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -125,5 +125,5 @@ Debug: Complex { real: 3.3, imag: 7.2 } [fmt]: https://doc.rust-lang.org/std/fmt/ [macros]: ../../macros.md [structs]: ../../custom_types/structs.md -[traits]: ../../trait.md +[traits]: https://doc.rust-lang.org/std/fmt/#formatting-traits [use]: ../../mod/use.md From f5fbe1fe8b79636451befaef3931ca12d63f3baa Mon Sep 17 00:00:00 2001 From: abdo Date: Tue, 16 Feb 2021 05:59:33 +0300 Subject: [PATCH 1096/1122] Update function name in comment --- src/scope/lifetime/static_lifetime.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scope/lifetime/static_lifetime.md b/src/scope/lifetime/static_lifetime.md index c9a9d095c8..3f31693faa 100644 --- a/src/scope/lifetime/static_lifetime.md +++ b/src/scope/lifetime/static_lifetime.md @@ -85,7 +85,7 @@ fn main() { print_it(i); // oops, &i only has the lifetime defined by the scope of - // use_it(), so it's not 'static: + // main(), so it's not 'static: print_it(&i); } ``` From 69b013d775015a137d4714f4b6a9325d511ada9a Mon Sep 17 00:00:00 2001 From: Martin Ombura Jr Date: Tue, 23 Feb 2021 08:32:15 +0200 Subject: [PATCH 1097/1122] Update cast.md fixes minor spelling error 'incures' -> 'incurs' in type/casting.md --- src/types/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/cast.md b/src/types/cast.md index 2ca18c1784..13108172db 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -70,7 +70,7 @@ fn main() { // nan as u8 is 0 println!("nan as u8 is {}", f32::NAN as u8); - // This behavior incures a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: + // This behavior incurs a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: unsafe { // 300.0 is 44 println!("300.0 is {}", 300.0_f32.to_int_unchecked::()); From 53960f30c15b8981c8c612fd85dda0664e406f82 Mon Sep 17 00:00:00 2001 From: Emil Luta Date: Wed, 24 Feb 2021 22:05:26 +0000 Subject: [PATCH 1098/1122] Make flow_control/for/.into_iter() example run For: `https://doc.rust-lang.org/rust-by-example/flow_control/for.html`, the example containing `.into_iter()` the suggestion is to comment the line trying to print the vector, after move. This code throws compilation error. In order to fix this, commit `4cc85655b97be83acbca5d036cf679f39ea66eb8` has been introduced. This indeed makes the example pass the tests, but disables the run option. Now, if I want to learn, I need to copy paste the example in my own editor and compile it, rather than being able to click run, comment as suggested and click run again. This commit fixes this issue. Alongside, it makes the style of playpen attributes consistent with the rest of the book (majority, seems `rust,editable` is preferred over `rust, editable`). --- src/flow_control/for.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flow_control/for.md b/src/flow_control/for.md index 23445fe4fd..b5d5d62721 100644 --- a/src/flow_control/for.md +++ b/src/flow_control/for.md @@ -60,7 +60,7 @@ within. * `iter` - This borrows each element of the collection through each iteration. Thus leaving the collection untouched and available for reuse after the loop. -```rust, editable +```rust,editable fn main() { let names = vec!["Bob", "Frank", "Ferris"]; @@ -80,7 +80,7 @@ fn main() { data is provided. Once the collection has been consumed it is no longer available for reuse as it has been 'moved' within the loop. -```rust, editable, ignore +```rust,editable,ignore,mdbook-runnable fn main() { let names = vec!["Bob", "Frank", "Ferris"]; @@ -99,7 +99,7 @@ fn main() { * `iter_mut` - This mutably borrows each element of the collection, allowing for the collection to be modified in place. -```rust, editable +```rust,editable fn main() { let mut names = vec!["Bob", "Frank", "Ferris"]; From a48ec1df66f1964f1b5fdbd34b89cad90e437686 Mon Sep 17 00:00:00 2001 From: ejose19 <8742215+ejose19@users.noreply.github.com> Date: Thu, 25 Feb 2021 12:14:34 -0300 Subject: [PATCH 1099/1122] Add destructuring example to generics new type Would be great to have both examples so new users can get to know the other way to do it. --- src/generics/new_types.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/generics/new_types.md b/src/generics/new_types.md index ccbbbb03cf..c819002c28 100644 --- a/src/generics/new_types.md +++ b/src/generics/new_types.md @@ -40,13 +40,14 @@ fn main() { Uncomment the last print statement to observe that the type supplied must be `Years`. -To obtain the `newtype`'s value as the base type, you may use tuple syntax like so: +To obtain the `newtype`'s value as the base type, you may use the tuple or destructuring syntax like so: ```rust, editable struct Years(i64); fn main() { let years = Years(42); - let years_as_primitive: i64 = years.0; + let years_as_primitive_1: i64 = years.0; // Tuple + let Years(years_as_primitive_2) = years; // Destructuring } ``` From ad71e72d14f470be9a45822a58a4706f43e7a5d9 Mon Sep 17 00:00:00 2001 From: 4geru Date: Mon, 1 Mar 2021 06:37:06 +0900 Subject: [PATCH 1100/1122] remove new line --- src/custom_types/structs.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 0dfc261292..6c7976df27 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -3,8 +3,7 @@ There are three types of structures ("structs") that can be created using the `struct` keyword: -* Tuple structs, which are, basically, named tuples. -* The classic [C structs][c_struct] +* Tuple structs, which are, basically, named tuples. The classic [C structs][c_struct] * Unit structs, which are field-less, are useful for generics. ```rust,editable From 8e2c3253d0c584902912cea98796ae547f8156aa Mon Sep 17 00:00:00 2001 From: 4geru Date: Mon, 1 Mar 2021 06:56:46 +0900 Subject: [PATCH 1101/1122] fix name from rectangle to Rectangle --- src/custom_types/structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 0dfc261292..251fda36bf 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -86,7 +86,7 @@ fn main() { ### Activity -1. Add a function `rect_area` which calculates the area of a rectangle (try +1. Add a function `rect_area` which calculates the area of a `Rectangle` (try using nested destructuring). 2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and From e77c80fdc035b69a8aa1d33db12f42543be8da89 Mon Sep 17 00:00:00 2001 From: Darius Wiles Date: Tue, 2 Mar 2021 13:34:39 -0800 Subject: [PATCH 1102/1122] Typo "incures" in code comment --- src/types/cast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/cast.md b/src/types/cast.md index 2ca18c1784..13108172db 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -70,7 +70,7 @@ fn main() { // nan as u8 is 0 println!("nan as u8 is {}", f32::NAN as u8); - // This behavior incures a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: + // This behavior incurs a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: unsafe { // 300.0 is 44 println!("300.0 is {}", 300.0_f32.to_int_unchecked::()); From 74a865ce6d335b6eb5fa0694f9ae658ca56a529d Mon Sep 17 00:00:00 2001 From: Darius Wiles Date: Wed, 3 Mar 2021 15:09:32 -0800 Subject: [PATCH 1103/1122] Fix grammar "terminates" -> "terminate" --- src/fn/diverging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fn/diverging.md b/src/fn/diverging.md index 19cf27c080..52e1f819ae 100644 --- a/src/fn/diverging.md +++ b/src/fn/diverging.md @@ -66,4 +66,4 @@ fn main() { ``` It is also the return type of functions that loop forever (e.g. `loop {}`) like -network servers or functions that terminates the process (e.g. `exit()`). +network servers or functions that terminate the process (e.g. `exit()`). From b53089bbee6db486b58c07a665c999adc3fcb454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Sat, 13 Mar 2021 23:50:54 +0100 Subject: [PATCH 1104/1122] Changed impl to use Self::Item --- src/trait/iter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trait/iter.md b/src/trait/iter.md index 9c9540985b..3c5e5451e6 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -24,7 +24,7 @@ impl Iterator for Fibonacci { // The return type is `Option`: // * When the `Iterator` is finished, `None` is returned. // * Otherwise, the next value is wrapped in `Some` and returned. - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { let new_next = self.curr + self.next; self.curr = self.next; From c7829980dbe9ad4282b4f809ab635508e75b017b Mon Sep 17 00:00:00 2001 From: r00ster Date: Mon, 15 Mar 2021 20:43:27 +0100 Subject: [PATCH 1105/1122] Add missing code highlighting --- src/expression.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/expression.md b/src/expression.md index 467bc10646..27a278d027 100644 --- a/src/expression.md +++ b/src/expression.md @@ -2,7 +2,7 @@ A Rust program is (mostly) made up of a series of statements: -``` +```rust,editable fn main() { // statement // statement @@ -13,7 +13,7 @@ fn main() { There are a few kinds of statements in Rust. The most common two are declaring a variable binding, and using a `;` with an expression: -``` +```rust,editable fn main() { // variable binding let x = 5; From ad142f295df89bb399eeefc73903215540b7466b Mon Sep 17 00:00:00 2001 From: r00ster Date: Mon, 15 Mar 2021 20:50:26 +0100 Subject: [PATCH 1106/1122] Correct code highlighting --- src/primitives/tuples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitives/tuples.md b/src/primitives/tuples.md index 7e29ef22c7..82f4083fc9 100644 --- a/src/primitives/tuples.md +++ b/src/primitives/tuples.md @@ -64,7 +64,7 @@ fn main() { ### Activity - 1. *Recap*: Add the `fmt::Display` trait to the Matrix `struct` in the above example, + 1. *Recap*: Add the `fmt::Display` trait to the `Matrix` struct in the above example, so that if you switch from printing the debug format `{:?}` to the display format `{}`, you see the following output: From 9540aa2bd4e862956917260930ae8a2a053026ba Mon Sep 17 00:00:00 2001 From: r00ster Date: Mon, 15 Mar 2021 20:53:25 +0100 Subject: [PATCH 1107/1122] Correct code highlighting --- src/hello/print/print_display.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print/print_display.md b/src/hello/print/print_display.md index 1ff31f27ac..064fe6ded5 100644 --- a/src/hello/print/print_display.md +++ b/src/hello/print/print_display.md @@ -108,7 +108,7 @@ each requires its own implementation. This is detailed further in ### Activity After checking the output of the above example, use the `Point2D` struct as a -guide to add a Complex struct to the example. When printed in the same +guide to add a `Complex` struct to the example. When printed in the same way, the output should be: ```txt From 80013576478e3200332a1deff4a9699ae297baa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Wed, 17 Mar 2021 00:10:34 +0100 Subject: [PATCH 1108/1122] Added documentation for Self::Item --- src/trait/iter.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/trait/iter.md b/src/trait/iter.md index 3c5e5451e6..2af4fcb784 100644 --- a/src/trait/iter.md +++ b/src/trait/iter.md @@ -18,12 +18,15 @@ struct Fibonacci { // Implement `Iterator` for `Fibonacci`. // The `Iterator` trait only requires a method to be defined for the `next` element. impl Iterator for Fibonacci { + // We can refer to this type using Self::Item type Item = u32; // Here, we define the sequence using `.curr` and `.next`. // The return type is `Option`: // * When the `Iterator` is finished, `None` is returned. // * Otherwise, the next value is wrapped in `Some` and returned. + // We use Self::Item in the return type, so we can change + // the type without having to update the function signatures. fn next(&mut self) -> Option { let new_next = self.curr + self.next; From a86072725f6df73328d95d685bedf01c2aea3620 Mon Sep 17 00:00:00 2001 From: sade <41547641+sumade123@users.noreply.github.com> Date: Wed, 17 Mar 2021 15:01:37 +0000 Subject: [PATCH 1109/1122] Update multi_bounds.md --- src/generics/multi_bounds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generics/multi_bounds.md b/src/generics/multi_bounds.md index 5f51a6c24b..969ba6417e 100644 --- a/src/generics/multi_bounds.md +++ b/src/generics/multi_bounds.md @@ -1,6 +1,6 @@ # Multiple bounds -Multiple bounds can be applied with a `+`. Like normal, different types are +Multiple bounds for a single type can be applied with a `+`. Like normal, different types are separated with `,`. ```rust,editable From 48355aa9692088d84cfedd79802ef02fe1bc1d3b Mon Sep 17 00:00:00 2001 From: LudwikJaniuk Date: Sat, 20 Mar 2021 15:47:18 +0100 Subject: [PATCH 1110/1122] Reformulated text for redability --- src/scope/move/partial_move.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/scope/move/partial_move.md b/src/scope/move/partial_move.md index 7afa7e5419..98c6c8dc81 100644 --- a/src/scope/move/partial_move.md +++ b/src/scope/move/partial_move.md @@ -1,11 +1,12 @@ # Partial moves -Pattern bindings can have `by-move` and `by-reference` bindings at -the same time which is used in [destructuring]. Using these pattern -will result in partial move for the variable, which means that part -of the variable is moved while other parts stayed. In this case, the -parent variable cannot be used afterwards as a whole. However, parts -of it that are referenced and not moved can be used. +Within the [destructuring] of a single variable, both `by-move` and +`by-reference` pattern bindings can be used at the same time. Doing +this will result in a _partial move_ of the variable, which means +that parts of the variable will be moved while other parts stay. In +such a case, the parent variable cannot be used afterwards as a +whole, however the parts that are only referenced (and not moved) +can still be used. ```rust,editable fn main() { @@ -37,4 +38,4 @@ fn main() { ### See also: [destructuring][destructuring] -[destructuring]: ../../flow_control/match/destructuring.md \ No newline at end of file +[destructuring]: ../../flow_control/match/destructuring.md From 84e80f7a628008cd03255b29a0987a22df38d697 Mon Sep 17 00:00:00 2001 From: gpk2000 Date: Sun, 21 Mar 2021 19:56:20 +0530 Subject: [PATCH 1111/1122] broken long comments in src/types/cast.md to several shortones --- src/types/cast.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/types/cast.md b/src/types/cast.md index 2ca18c1784..770a9e6ebe 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -22,7 +22,8 @@ fn main() { let integer = decimal as u8; let character = integer as char; - // Error! There are limitations in conversion rules. A float cannot be directly converted to a char. + // Error! There are limitations in conversion rules. + // A float cannot be directly converted to a char. let character = decimal as char; // FIXME ^ Comment out this line @@ -60,8 +61,10 @@ fn main() { // and the two's complement of 232 is -24 println!(" 232 as a i8 is : {}", 232 as i8); - // Since Rust 1.45, the `as` keyword performs a *saturating cast* when casting from float to int. - // If the floating point value exceeds the upper bound or is less than the lower bound, the returned value will be equal to the bound crossed. + // Since Rust 1.45, the `as` keyword performs a *saturating cast* + // when casting from float to int. If the floating point value exceeds + // the upper bound or is less than the lower bound, the returned value + // will be equal to the bound crossed. // 300.0 is 255 println!("300.0 is {}", 300.0_f32 as u8); @@ -70,7 +73,9 @@ fn main() { // nan as u8 is 0 println!("nan as u8 is {}", f32::NAN as u8); - // This behavior incures a small runtime cost and can be avoided with unsafe methods, however the results might overflow and return **unsound values**. Use these methods wisely: + // This behavior incures a small runtime cost and can be avoided + // with unsafe methods, however the results might overflow and + // return **unsound values**. Use these methods wisely: unsafe { // 300.0 is 44 println!("300.0 is {}", 300.0_f32.to_int_unchecked::()); From e3cfa2c7358615f685f7124cbbfa17b090c81ff4 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 23 Mar 2021 10:52:38 +0100 Subject: [PATCH 1112/1122] Unwrap some drinks. Fixes #1424 --- src/error/option_unwrap.md | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/error/option_unwrap.md b/src/error/option_unwrap.md index df02b8c113..5192767fcc 100644 --- a/src/error/option_unwrap.md +++ b/src/error/option_unwrap.md @@ -1,13 +1,13 @@ # `Option` & `unwrap` In the last example, we showed that we can induce program failure at will. -We told our program to `panic` if the royal received an inappropriate -gift - a snake. But what if the royal expected a gift and didn't receive -one? That case would be just as bad, so it needs to be handled! +We told our program to `panic` if we drink a sugary lemonade. +But what if we expect _some_ drink but don't receive one? +That case would be just as bad, so it needs to be handled! -We *could* test this against the null string (`""`) as we do with a snake. +We *could* test this against the null string (`""`) as we do with a lemonade. Since we're using Rust, let's instead have the compiler point out cases -where there's no gift. +where there's no drink. An `enum` called `Option` in the `std` library is used when absence is a possibility. It manifests itself as one of two "options": @@ -24,41 +24,41 @@ handling. In the following example, explicit handling yields a more controlled result while retaining the option to `panic` if desired. ```rust,editable,ignore,mdbook-runnable -// The commoner has seen it all, and can handle any gift well. -// All gifts are handled explicitly using `match`. -fn give_commoner(gift: Option<&str>) { +// The adult has seen it all, and can handle any drink well. +// All drinks are handled explicitly using `match`. +fn give_adult(drink: Option<&str>) { // Specify a course of action for each case. - match gift { - Some("snake") => println!("Yuck! I'm putting this snake back in the forest."), + match drink { + Some("lemonade") => println!("Yuck! Too sugary."), Some(inner) => println!("{}? How nice.", inner), - None => println!("No gift? Oh well."), + None => println!("No drink? Oh well."), } } -// Our sheltered royal will `panic` at the sight of snakes. -// All gifts are handled implicitly using `unwrap`. -fn give_royal(gift: Option<&str>) { +// Others will `panic` before drinking sugary drinks. +// All drinks are handled implicitly using `unwrap`. +fn drink(drink: Option<&str>) { // `unwrap` returns a `panic` when it receives a `None`. - let inside = gift.unwrap(); - if inside == "snake" { panic!("AAAaaaaa!!!!"); } + let inside = drink.unwrap(); + if inside == "lemonade" { panic!("AAAaaaaa!!!!"); } println!("I love {}s!!!!!", inside); } fn main() { - let food = Some("cabbage"); - let snake = Some("snake"); + let water = Some("water"); + let lemonade = Some("lemonade"); let void = None; - give_commoner(food); - give_commoner(snake); - give_commoner(void); + give_adult(water); + give_adult(lemonade); + give_adult(void); - let bird = Some("robin"); + let coffee = Some("coffee"); let nothing = None; - give_royal(bird); - give_royal(nothing); + drink(coffee); + drink(nothing); } ``` From beaef7d69bc1e74537536a1f98916fdb25a4580a Mon Sep 17 00:00:00 2001 From: AbserAri <32089134+abserari@users.noreply.github.com> Date: Thu, 8 Apr 2021 10:49:46 +0800 Subject: [PATCH 1113/1122] fix compile bug with panic! ```bash Compiling playground v0.0.1 (/playground) warning: panic message is not a string literal --> src/main.rs:48:32 | 48 | Err(why) => panic!(match why { | ________________________________^ 49 | | MathError::NonPositiveLogarithm 50 | | => "logarithm of non-positive number", 51 | | MathError::DivisionByZero ... | 54 | | => "square root of negative number", 55 | | }), | |_____________^ | = note: `#[warn(non_fmt_panic)]` on by default = note: this is no longer accepted in Rust 2021 help: add a "{}" format string to Display the message | 48 | Err(why) => panic!("{}", match why { | ^^^^^ help: or use std::panic::panic_any instead | 48 | Err(why) => std::panic::panic_any(match why { | ^^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted Finished dev [unoptimized + debuginfo] target(s) in 1.46s Running `target/debug/playground` thread 'main' panicked at 'square root of negative number', src/main.rs:48:25 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` --- src/std/result/question_mark.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/result/question_mark.md b/src/std/result/question_mark.md index c51cc638f6..a1f7706840 100644 --- a/src/std/result/question_mark.md +++ b/src/std/result/question_mark.md @@ -54,7 +54,7 @@ mod checked { pub fn op(x: f64, y: f64) { match op_(x, y) { - Err(why) => panic!(match why { + Err(why) => panic!("{}", match why { MathError::NonPositiveLogarithm => "logarithm of non-positive number", MathError::DivisionByZero From caf3b729bf939e3680527f4352042fdc8877b8cc Mon Sep 17 00:00:00 2001 From: imjoey Date: Tue, 27 Apr 2021 17:01:38 +0800 Subject: [PATCH 1114/1122] chore: Fix the indention of Borrowed definition Signed-off-by: imjoey --- src/scope/lifetime/trait.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scope/lifetime/trait.md b/src/scope/lifetime/trait.md index 0f56f5b4c1..3c26df1194 100644 --- a/src/scope/lifetime/trait.md +++ b/src/scope/lifetime/trait.md @@ -6,9 +6,9 @@ Note that `impl` may have annotation of lifetimes too. ```rust,editable // A struct with annotation of lifetimes. #[derive(Debug)] - struct Borrowed<'a> { - x: &'a i32, - } +struct Borrowed<'a> { + x: &'a i32, +} // Annotate lifetimes to impl. impl<'a> Default for Borrowed<'a> { From a3e714dc7ecadbd046ce4a2843e187def9518f40 Mon Sep 17 00:00:00 2001 From: Pavan <56096830+gpk2000@users.noreply.github.com> Date: Tue, 27 Apr 2021 17:50:18 +0530 Subject: [PATCH 1115/1122] Update cast.md --- src/types/cast.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types/cast.md b/src/types/cast.md index 603f25c5c1..79e070d375 100644 --- a/src/types/cast.md +++ b/src/types/cast.md @@ -73,7 +73,6 @@ fn main() { // nan as u8 is 0 println!("nan as u8 is {}", f32::NAN as u8); - // This behavior incurs a small runtime cost and can be avoided // with unsafe methods, however the results might overflow and // return **unsound values**. Use these methods wisely: From c467fc68b4b9f001f5ce12c84e0e7cf4fe33b43c Mon Sep 17 00:00:00 2001 From: mautamu Date: Wed, 28 Apr 2021 20:28:32 -0500 Subject: [PATCH 1116/1122] Fix Typo in LRBE section; closes #1434 --- src/hello/print.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello/print.md b/src/hello/print.md index e09f128ebc..89d2aa0de3 100644 --- a/src/hello/print.md +++ b/src/hello/print.md @@ -39,7 +39,7 @@ fn main() { println!("{number:>width$}", number=1, width=6); // You can pad numbers with extra zeroes. This will output "000001". - println!("{number:>0width$}", number=1, width=6); + println!("{number:0>width$}", number=1, width=6); // Rust even checks to make sure the correct number of arguments are // used. From c66f0d7f1e743167295d10779fa2674f69c4ae89 Mon Sep 17 00:00:00 2001 From: mautamu Date: Wed, 28 Apr 2021 21:26:39 -0500 Subject: [PATCH 1117/1122] Add some tests to cargo/test.md. Partially addresses #1304 --- src/cargo/test.md | 85 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index b4bc69d5c5..27f265278d 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -14,12 +14,19 @@ foo ├── Cargo.toml ├── src │ └── main.rs +│ └── lib.rs └── tests ├── my_test.rs └── my_other_test.rs ``` -Each file in `tests` is a separate integration test. +Each file in `tests` is a separate +[integration test](https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests), +i.e. a test that is meant to test your library as if it were being called from a dependent +crate. + +The [Testing](testing.md) chapter elaborates on the three different testing styles: +[Unit](testing/unit_testing.md), [Doc](testing/doc_testing.md), and [Integration](testing/integration_testing.md). `cargo` naturally provides an easy way to run all of your tests! @@ -64,5 +71,77 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out ``` One word of caution: Cargo may run multiple tests concurrently, so make sure -that they don't race with each other. For example, if they all output to a -file, you should make them write to different files. +that they don't race with each other. + +One example of this concurrency causing issues is if two tests output to a +file, such as below: + +```rust +#[cfg(test)] +mod tests { + // Import the necessary modules + use std::fs::OpenOptions; + use std::io::Write; + + // This test writes to a file + #[test] + fn test_file() { + // Opens the file ferris.txt or creates one if it doesn't exist. + let mut file = OpenOptions::new() + .append(true) + .create(true) + .open("ferris.txt") + .expect("Failed to open ferris.txt"); + + // Print "Ferris" 5 times. + for _ in 0..5 { + file.write_all("Ferris\n".as_bytes()) + .expect("Could not write to ferris.txt"); + } + } + + // This test tries to write to the same file + #[test] + fn test_file_also() { + // Opens the file ferris.txt or creates one if it doesn't exist. + let mut file = OpenOptions::new() + .append(true) + .create(true) + .open("ferris.txt") + .expect("Failed to open ferris.txt"); + + // Print "Corro" 5 times. + for _ in 0..5 { + file.write_all("Corro\n".as_bytes()) + .expect("Could not write to ferris.txt"); + } + } +} +``` + +Although the intent is to get the following: +``` +Ferris +Ferris +Ferris +Ferris +Ferris +Corro +Corro +Corro +Corro +Corro +``` +What actually gets put into `ferris.txt` is this: +``` +Corro +Ferris +Corro +Ferris +Corro +Ferris +Corro +Ferris +Corro +Ferris +``` From cb9e82723f77ad81aaee0cd067c2e64af72f10cd Mon Sep 17 00:00:00 2001 From: mautamu Date: Wed, 28 Apr 2021 22:09:05 -0500 Subject: [PATCH 1118/1122] Fix mistake in codeblock definitions --- src/cargo/test.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index 27f265278d..e28c200659 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -120,7 +120,8 @@ mod tests { ``` Although the intent is to get the following: -``` +```shell +$ cat ferris.txt Ferris Ferris Ferris @@ -133,7 +134,8 @@ Corro Corro ``` What actually gets put into `ferris.txt` is this: -``` +```shell +$ cargo test test_foo Corro Ferris Corro From fb8b522b8c2ee0b770cd09cfaef9b660140ffd4c Mon Sep 17 00:00:00 2001 From: mautamu Date: Wed, 28 Apr 2021 23:51:15 -0500 Subject: [PATCH 1119/1122] Fix broken link mistake --- src/cargo/test.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cargo/test.md b/src/cargo/test.md index e28c200659..01884a09af 100644 --- a/src/cargo/test.md +++ b/src/cargo/test.md @@ -25,8 +25,8 @@ Each file in `tests` is a separate i.e. a test that is meant to test your library as if it were being called from a dependent crate. -The [Testing](testing.md) chapter elaborates on the three different testing styles: -[Unit](testing/unit_testing.md), [Doc](testing/doc_testing.md), and [Integration](testing/integration_testing.md). +The [Testing][testing] chapter elaborates on the three different testing styles: +[Unit][unit_testing], [Doc][doc_testing], and [Integration][integration_testing]. `cargo` naturally provides an easy way to run all of your tests! @@ -147,3 +147,8 @@ Ferris Corro Ferris ``` + +[testing]: ../testing.md +[unit_testing]: ../testing/unit_testing.md +[integration_testing]: ../testing/unit_testing.md +[doc_testing]: ../testing/doc_testing.md From 3bc969cad8bfab664b4bc9f2832212d41752d649 Mon Sep 17 00:00:00 2001 From: Tyler Turk Date: Thu, 20 May 2021 12:39:51 -0500 Subject: [PATCH 1120/1122] Update structs.md It seems like the variables here are flipped. When implementing the rectangle area method, I noticed that my area should be 0 and discovered this. --- src/custom_types/structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 227a261fb5..90dac52b6f 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -59,7 +59,7 @@ fn main() { println!("second point: ({}, {})", bottom_right.x, bottom_right.y); // Destructure the point using a `let` binding - let Point { x: top_edge, y: left_edge } = point; + let Point { x: left_edge, y: top_edge } = point; let _rectangle = Rectangle { // struct instantiation is an expression too From 1ff687f5a71a25d97b05fe851f7a6421ccb195d2 Mon Sep 17 00:00:00 2001 From: Jimmy Lu Date: Sat, 26 Jun 2021 13:19:43 -0400 Subject: [PATCH 1121/1122] Fix Structures type list --- src/custom_types/structs.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/custom_types/structs.md b/src/custom_types/structs.md index 90dac52b6f..508cff2314 100644 --- a/src/custom_types/structs.md +++ b/src/custom_types/structs.md @@ -3,7 +3,8 @@ There are three types of structures ("structs") that can be created using the `struct` keyword: -* Tuple structs, which are, basically, named tuples. The classic [C structs][c_struct] +* Tuple structs, which are, basically, named tuples. +* The classic [C structs][c_struct] * Unit structs, which are field-less, are useful for generics. ```rust,editable From d872e19e9c586836ef859880974aed7a5b5c8c68 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Mon, 5 Jul 2021 20:52:52 -0400 Subject: [PATCH 1122/1122] Fix a couple of typos in the integration_testing.md file --- src/testing/integration_testing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testing/integration_testing.md b/src/testing/integration_testing.md index a4345ae945..0ac77588c3 100644 --- a/src/testing/integration_testing.md +++ b/src/testing/integration_testing.md @@ -47,8 +47,8 @@ running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` -Each Rust source file in `tests` directory is compiled as a separate crate. One -way of sharing some code between integration tests is making module with public +Each Rust source file in the `tests` directory is compiled as a separate crate. One +way of sharing some code between integration tests is making a module with public functions, importing and using it within tests. File `tests/common.rs`:

(&mut self, predicate: P) -> Option where // `FnMut` meaning any captured variable may at most be From 41540a59696dc2dbd9f850e9ef34d7c529850888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Toma=C5=BEi=C4=8D?= Date: Fri, 31 Jul 2015 14:49:55 +0200 Subject: [PATCH 0310/1122] Add same scope binding shadowing Add an example of shadowing a variable binding in the same scope. --- examples/variable_bindings/scope/scope.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/variable_bindings/scope/scope.rs b/examples/variable_bindings/scope/scope.rs index 567d2eca2e..4d923989e7 100644 --- a/examples/variable_bindings/scope/scope.rs +++ b/examples/variable_bindings/scope/scope.rs @@ -21,4 +21,9 @@ fn main() { // FIXME ^ Comment out this line println!("outer long: {}", long_lived_binding); + + // This binding also *shadows* the previous binding + let long_lived_binding = 'a'; + + println!("outer long: {}", long_lived_binding); } From 63282de8feb5734799767bcba2929036496f4abd Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 31 Jul 2015 14:05:19 -0400 Subject: [PATCH 0311/1122] Remove getopts This is based on the rustc_private flag, which shouldn't be used, and causes confusion: https://users.rust-lang.org/t/noob-diff-cargo-v-feature-rustc-private/2277 Until we can use external crates, it's better to just not have this. --- examples/std_misc/arg/getopts/echo.rs | 67 ----------------------- examples/std_misc/arg/getopts/input.md | 70 ------------------------ examples/std_misc/arg/getopts/test.sh | 20 ------- examples/std_misc/arg/getopts/testopt.rs | 41 -------------- examples/std_misc/arg/matching/input.md | 4 -- examples/structure.json | 3 +- 6 files changed, 1 insertion(+), 204 deletions(-) delete mode 100644 examples/std_misc/arg/getopts/echo.rs delete mode 100644 examples/std_misc/arg/getopts/input.md delete mode 100644 examples/std_misc/arg/getopts/test.sh delete mode 100644 examples/std_misc/arg/getopts/testopt.rs diff --git a/examples/std_misc/arg/getopts/echo.rs b/examples/std_misc/arg/getopts/echo.rs deleted file mode 100644 index 0316b85c2d..0000000000 --- a/examples/std_misc/arg/getopts/echo.rs +++ /dev/null @@ -1,67 +0,0 @@ -#![feature(rustc_private)] - -extern crate getopts; - -use std::env; -use std::io; -use std::io::Write; -use std::process; - -static VERSION: &'static str = "1.0.0"; - -fn main() { - let args: Vec = env::args().collect(); - let ref program = args[0]; - - // Set possible flags. - // The first argument to `optflag` is the short flag name. - // The second argument is the long flag name. - // The third argument is the help text. - let opts = [ - getopts::optflag("n", "", "do not output the trailing newline"), - getopts::optflag("h", "help", "display this help and exit"), - getopts::optflag("V", "version", - "output version information and exit"), - ]; - - let matches = match getopts::getopts(&args[1..], &opts) { - Ok(m) => m, - Err(f) => { - println!("{}", f); - process::exit(1); - // The exit code is 0 (success) by default. - // Any exit code other than 0 indicates failure. - } - }; - - if matches.opt_present("help") { - //^ We could as well have used the short name: "h" - println!("echo {} - display a line of text", VERSION); - println!(""); - println!("Usage:"); - println!(" {} [SHORT-OPTION]... [STRING]...", program); - println!(" {} LONG-OPTION", program); - println!(""); - let usage = getopts::usage("Echo the STRING(s) to standard output.", - &opts); - println!("{}", usage); - return; - } - - if matches.opt_present("version") { - println!("echo version: {}", VERSION); - return; - } - - if !matches.free.is_empty() { - //^ `matches.free` contains all the arguments that are not options. - let string = matches.free.join(" "); - println!("{}", string); - } - - if !matches.opt_present("n") { - println!("") - } else { - let _ = io::stdout().flush(); - } -} diff --git a/examples/std_misc/arg/getopts/input.md b/examples/std_misc/arg/getopts/input.md deleted file mode 100644 index 1ca22095d7..0000000000 --- a/examples/std_misc/arg/getopts/input.md +++ /dev/null @@ -1,70 +0,0 @@ -To build unix-style command line interfaces, you can use the [getopts](http://doc.rust-lang.org/getopts/index.html) crate. - -Here is a simple implementation of the `echo` unix program: - -{echo.play} - -``` -$ ./echo -h -echo 1.0.0 - display a line of text - -Usage: - ./echo [SHORT-OPTION]... [STRING]... - ./echo LONG-OPTION - -Echo the STRING(s) to standard output. - -Options: - -n do not output the trailing newline - -h --help display this help and exit - -V --version output version information and exit - -$ ./echo --version -echo version: 1.0.0 -$ ./echo Hello, World! -Hello, World! -``` - -This is a simplified version of the implementation in -[uutils](https://github.com/uutils/coreutils). - - -It is also possible to use *options* instead of *flags*, such that values can -be passed to the program: - -{testopt.rs} - -Here are some examples how the program behaves given different combinations of -arguments: - -``` -$ ./testopt -a=false, b=false, c="" -$ ./testopt -a -b -a=true, b=true, c="" -$ ./testopt -ab -a=true, b=true, c="" -$ ./testopt -c -Argument to option 'c' missing. -$ ./testopt -c value -a=false, b=false, c="value" -$ ./testopt -c=value -a=false, b=false, c="=value" -$ ./testopt -cvalue -a=false, b=false, c="value" -$ ./testopt arg -a=false, b=false, c="" -free arguments: [arg] -$ ./testopt -a arg -a=true, b=false, c="" -free arguments: [arg] -$ ./testopt -c value arg -a=false, b=false, c="value" -free arguments: [arg] -$ ./testopt -a -- -b -a=true, b=false, c="" -free arguments: [-b] -$ ./testopt -a - -a=true, b=false, c="" -free arguments: [-] -``` diff --git a/examples/std_misc/arg/getopts/test.sh b/examples/std_misc/arg/getopts/test.sh deleted file mode 100644 index 9beb289f1d..0000000000 --- a/examples/std_misc/arg/getopts/test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Generate the example output for input.md. - -function run { - echo '$' $1 - $1 -} - -run './testopt' -run './testopt -a -b' -run './testopt -ab' -run './testopt -c' -run './testopt -c value' -run './testopt -c=value' -run './testopt -cvalue' -run './testopt arg' -run './testopt -a arg' -run './testopt -c value arg' -run './testopt -a -- -b' -run './testopt -a -' diff --git a/examples/std_misc/arg/getopts/testopt.rs b/examples/std_misc/arg/getopts/testopt.rs deleted file mode 100644 index 25302bbea8..0000000000 --- a/examples/std_misc/arg/getopts/testopt.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![feature(rustc_private)] - -extern crate getopts; - -use std::env; -use std::process; - -fn main() { - let args: Vec = env::args().collect(); - - let opts = [ - getopts::optflag("a", "long_a", ""), - getopts::optflag("b", "long_b", ""), - getopts::optopt("c", "long_c", "", "VALUE"), - //^ Use `optflagopt` if the argument should be optional. - // Use `reqopt` if the option is required. - // Use `optmulti`, `optflagmulti` if options can occur multiple times. - ]; - - let matches = match getopts::getopts(&args[1..], &opts) { - Ok(m) => m, - Err(f) => { - println!("{}", f); - process::exit(1); - } - }; - let a = if matches.opt_present("a") {true} else {false}; - let b = if matches.opt_present("b") {true} else {false}; - let c = match matches.opt_str("c") { - Some(s) => s, - None => String::from(""), - }; - //^ Use `matches.opt_default` if you need a default (`opflagopt`). - // Use `matches.opt_count` if you need to count how many were matched - // (`*multi`). - - println!("a={}, b={}, c=\"{}\"", a, b, c); - if !matches.free.is_empty() { - println!("free arguments: {:?}", matches.free); - } -} diff --git a/examples/std_misc/arg/matching/input.md b/examples/std_misc/arg/matching/input.md index e27533f9c4..86645aa73e 100644 --- a/examples/std_misc/arg/matching/input.md +++ b/examples/std_misc/arg/matching/input.md @@ -24,7 +24,3 @@ match_args {increase|decrease} $ ./match_args increase 42 43 ``` - -The next example demonstrates `getopts` as a way to build more advanced, -unix-like command line interfaces. - diff --git a/examples/structure.json b/examples/structure.json index cd9ddf73bf..9753e708b3 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -167,8 +167,7 @@ ] }, { "id": "fs", "title": "Filesystem Operations", "children": null }, { "id": "arg", "title": "Program arguments", "children": [ - { "id": "matching", "title": "Argument parsing", "children": null }, - { "id": "getopts", "title": "`getopts`", "children": null } + { "id": "matching", "title": "Argument parsing", "children": null } ] }, { "id": "ffi", "title": "Foreign Function Interface", "children": null }, { "id": "simd", "title": "SIMD", "children": null } From c1456a45fc4bca6bf838d91cb4eed5b9e4feb315 Mon Sep 17 00:00:00 2001 From: DenisKolodin Date: Thu, 6 Aug 2015 11:15:39 +0300 Subject: [PATCH 0312/1122] Update clone.rs Pair don't implement core::fmt::Display --- examples/trait/clone/clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/clone/clone.rs b/examples/trait/clone/clone.rs index 4a41bc2875..a4d1cb5b6d 100644 --- a/examples/trait/clone/clone.rs +++ b/examples/trait/clone/clone.rs @@ -35,7 +35,7 @@ fn main() { drop(moved_pair); // Error! `moved_pair` has been `drop`ed - //println!("copy: {}", moved_pair); + //println!("copy: {:?}", moved_pair); // TODO ^ Try uncommenting this line // Clone can still be used From 8b136c8878e9ddeada3e526b1753af1fc7ca48cd Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Thu, 6 Aug 2015 17:21:45 -0400 Subject: [PATCH 0313/1122] generics: Fix typo (possessive missing apostrophe). --- examples/generics/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generics/input.md b/examples/generics/input.md index cff71e8e9d..bfd54d0471 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -6,7 +6,7 @@ over. This will require a rather involving syntax, though it seems straightforward at first. A type is specified as generic by ``. There are 2 basic rules -regarding this which are applied *at* the types first use: +regarding this which are applied *at* the type's first use: * Any type previously and locally specified to be generic is generic. * Everything else is concrete (non-generic). From 9d42d6b4f224a479518cb754735fa8e8800a87b7 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Thu, 6 Aug 2015 17:22:07 -0400 Subject: [PATCH 0314/1122] std_misc/file: Use samples, not playpens, for I/O examples. Since the file samples aren't runnable, making them editable is not particularly useful. Moreover, until #73 is closed, it will also make those pages much easier to read in the sepia and night reading modes. --- examples/std_misc/file/create/input.md | 7 +++---- examples/std_misc/file/open/input.md | 3 +-- examples/std_misc/fs/input.md | 6 ++---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/std_misc/file/create/input.md b/examples/std_misc/file/create/input.md index 3088e39108..e99a09ab18 100644 --- a/examples/std_misc/file/create/input.md +++ b/examples/std_misc/file/create/input.md @@ -2,10 +2,9 @@ The `create` static method opens a file in write-only mode. If the file already existed, the old content is destroyed. Otherwise, a new file is created. -{create.play} +{create.rs} -As in the previous example, the playpen won't allow file I/O, so you'll hit one -of the failure paths. Here's the expected successful output: +Here's the expected successful output: ``` $ mkdir out @@ -21,7 +20,7 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ``` (As in the previous example, you are encouraged to test this example under -failure conditions) +failure conditions.) There is also a more generic `open_mode` method that can open files in other modes like: read+write, append, etc. diff --git a/examples/std_misc/file/open/input.md b/examples/std_misc/file/open/input.md index e065978b8e..bc5e51df22 100644 --- a/examples/std_misc/file/open/input.md +++ b/examples/std_misc/file/open/input.md @@ -3,9 +3,8 @@ The `open` static method can be used to open a file in read-only mode. A `File` owns a resource, the file descriptor and takes care of closing the file when it is `drop`ed. -{open.play} +{open.rs} -The playpen doesn't allow file I/O, so you'll hit one of the failure paths. Here's the expected successful output: ``` diff --git a/examples/std_misc/fs/input.md b/examples/std_misc/fs/input.md index 8435bacaac..0c147e35af 100644 --- a/examples/std_misc/fs/input.md +++ b/examples/std_misc/fs/input.md @@ -1,10 +1,9 @@ The `std::io::fs` module contains several functions that deal with the filesystem. -{fs.play} +{fs.rs} -You won't be able to run the previous code, because the playpen doesn't allow -file operations. Here's the expected successful output: +Here's the expected successful output: ``` $ rustc fs.rs && ./fs @@ -45,4 +44,3 @@ a [`cfg!`][cfg] [cfg]: /attribute/cfg.html - From 3f00f10a1bd3cc8a2c60035643759b602a96f3f9 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 9 Aug 2015 11:23:00 -0400 Subject: [PATCH 0315/1122] Add simpler example to scope/borrow/ref --- examples/scope/borrow/ref/ref.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/scope/borrow/ref/ref.rs b/examples/scope/borrow/ref/ref.rs index 810a15c22e..2079e61e3c 100644 --- a/examples/scope/borrow/ref/ref.rs +++ b/examples/scope/borrow/ref/ref.rs @@ -2,8 +2,18 @@ struct Point { x: i32, y: i32 } fn main() { + let c = 'y'; + + // A `ref` borrow on the left side of an assignment is equivalent to + // an `&` borrow on the right side. + let ref ref_c1 = c; + let ref_c2 = &c; + + println!("ref_c1 equals ref_c2: {}", *ref_c1 == *ref_c2); + let point = Point { x: 0, y: 0 }; + // `ref` is also valid when destructuring a struct. let _copy_of_x = { // `ref_to_x` is a reference to the `x` field of `point` let Point { x: ref ref_to_x, y: _ } = point; From 4894ccc9e1ebbccf7e714f902b1753af38ff8368 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 9 Aug 2015 11:33:28 -0400 Subject: [PATCH 0316/1122] Remove serialization and rand since they don't have working links anymore and use cargo --- examples/trait/derive/input.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index 9a428b15e2..c96a255f33 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -10,15 +10,10 @@ This is a list of the "derivable" traits: [`PartialEq`][partial-eq], [`Ord`][ord], [`PartialOrd`][partial-ord] -* Serialization: - [`Encodable`][encodable], - [`Decodable`][decodable] * [`Clone`][clone], to create `T` from `&T` via a copy. * [`Hash`][hash], to compute a hash from `&T`. -* `Rand`, to - create a random instance of a data type. * [`Default`][default], to create an empty instance of a data type. * `Zero`, to @@ -31,8 +26,6 @@ This is a list of the "derivable" traits: [partial-eq]: http://doc.rust-lang.org/std/cmp/trait.PartialEq.html [ord]: http://doc.rust-lang.org/std/cmp/trait.Ord.html [partial-ord]: http://doc.rust-lang.org/std/cmp/trait.PartialOrd.html -[encodable]: http://doc.rust-lang.org/serialize/trait.Encodable.html -[decodable]: http://doc.rust-lang.org/serialize/trait.Decodable.html [clone]: http://doc.rust-lang.org/std/clone/trait.Clone.html [hash]: http://doc.rust-lang.org/std/hash/trait.Hash.html [default]: http://doc.rust-lang.org/std/default/trait.Default.html From 0969ee0e7cfdffb7927e9cf533d31892f606067e Mon Sep 17 00:00:00 2001 From: mdinger Date: Sun, 9 Aug 2015 11:48:45 -0400 Subject: [PATCH 0317/1122] Fix thread::scoped warning --- examples/std_misc/threads/threads.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/std_misc/threads/threads.rs b/examples/std_misc/threads/threads.rs index f61d14e0d2..a0b8c37995 100644 --- a/examples/std_misc/threads/threads.rs +++ b/examples/std_misc/threads/threads.rs @@ -1,15 +1,21 @@ -#![feature(scoped)] - use std::thread; static NTHREADS: i32 = 10; // This is the `main` thread fn main() { + // Make a vector to hold the children which are spawned. + let mut children = vec![]; + for i in 0..NTHREADS { // Spin up another thread - let _ = thread::scoped(move || { + children.push(thread::spawn(move || { println!("this is thread number {}", i) - }); + })); + } + + for child in children { + // Wait for the thread to finish. Returns a result. + let _ = child.join(); } } From 8e3455a8ca3d329c771f5ab7b3d2359a550b8e3e Mon Sep 17 00:00:00 2001 From: Colin von Heuring Date: Thu, 13 Aug 2015 21:00:28 -0700 Subject: [PATCH 0318/1122] minor grammar fix --- examples/scope/lifetime/borrow/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/borrow/input.md b/examples/scope/lifetime/borrow/input.md index d61e1fe336..a6bb60d69c 100644 --- a/examples/scope/lifetime/borrow/input.md +++ b/examples/scope/lifetime/borrow/input.md @@ -23,7 +23,7 @@ enough". Let's analyze why this happens: * `'main` and `'let` are the scopes of the blocks * When a block scope ends, all the objects declared in it get destroyed * `'let` ends, and so does `'e` - * `'main` ends, and so does `'a` `'b` `'c` and `'d` + * `'main` ends, and so do `'a` `'b` `'c` and `'d` * `ref_to_box` is a valid borrow, because * `ref_to_box` has lifetime `'c` * `ref_to_box` points to an object with lifetime `'b` From 075705bb5b493dc8f15cf925a4822636a1c3e507 Mon Sep 17 00:00:00 2001 From: Colin von Heuring Date: Thu, 13 Aug 2015 21:01:36 -0700 Subject: [PATCH 0319/1122] minor grammar fix --- examples/custom_types/constants/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_types/constants/input.md b/examples/custom_types/constants/input.md index d45882506e..1dc71172c7 100644 --- a/examples/custom_types/constants/input.md +++ b/examples/custom_types/constants/input.md @@ -5,7 +5,7 @@ including global. Both require explicit type annotation: * `static`: A possibly `mut`able variable with [`'static`][static] lifetime. One special case is the `"string"` literal. It can be assigned directly to a -`static` variable without modification because it's type signature: +`static` variable without modification because its type signature: `&'static str` has the required lifetime of `'static`. All other reference types must be specifically annotated so that they fulfill the `'static` lifetime. This may seem minor though because the required explicit annotation From 7031c623f5c66d72bbfcb2fad0b28d960e9daae7 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 14 Aug 2015 13:24:37 -0400 Subject: [PATCH 0320/1122] Drop thread::scoped from update --- src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index cc45f0056c..08d1892c2b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ #![feature(iter_arith)] -#![feature(scoped)] #![deny(warnings)] -#![allow(deprecated)] // thread::scoped needs to go, but can't do it now +#![allow(deprecated)] #![feature(plugin)] extern crate regex; @@ -21,19 +20,22 @@ mod playpen; fn main() { let examples = Example::get_list(); let (tx, rx) = mpsc::channel(); + let mut children = vec![]; let mut nexamples = 0; for (i, example) in examples.into_iter().enumerate() { let tx = tx.clone(); let count = example.count(); - let _ = thread::scoped(move || { + children.push(thread::spawn(move || { example.process(vec!(i + 1), tx, 0, String::new()); - }); + })); nexamples += count; } + for child in children { let _ = child.join(); } + let mut entries = (0..nexamples).map(|_| { rx.recv().unwrap() }).collect::, String)>>(); From 125b4d40c2858829e1d7297c36f8325d98524f12 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 14 Aug 2015 13:24:44 -0400 Subject: [PATCH 0321/1122] Update cargo lock --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68946aaf1d..4a9e8a4635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,13 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -29,17 +29,17 @@ dependencies = [ [[package]] name = "regex" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] From 59d76095dbfaeebe569ec761b1ac687efc806399 Mon Sep 17 00:00:00 2001 From: mdinger Date: Tue, 30 Jun 2015 17:36:59 -0400 Subject: [PATCH 0322/1122] Rewrite lifetimes section --- examples/scope/lifetime/borrow/borrow.rs | 19 ----- examples/scope/lifetime/borrow/input.md | 53 ------------ examples/scope/lifetime/elision/elision.rs | 23 ++++++ examples/scope/lifetime/elision/input.md | 14 ++++ examples/scope/lifetime/explicit/explicit.rs | 44 ++++++---- examples/scope/lifetime/explicit/input.md | 36 ++++++--- examples/scope/lifetime/fn/fn.rs | 80 +++++++++---------- examples/scope/lifetime/fn/input.md | 15 +++- examples/scope/lifetime/input.md | 40 +++------- examples/scope/lifetime/lifetime.rs | 12 +++ .../scope/lifetime/lifetime_bounds/bounds.rs | 30 +++++++ .../scope/lifetime/lifetime_bounds/input.md | 17 ++++ .../lifetime/lifetime_coercion/coercion.rs | 21 +++++ .../scope/lifetime/lifetime_coercion/input.md | 4 + examples/scope/lifetime/methods/input.md | 10 +++ examples/scope/lifetime/methods/methods.rs | 17 ++++ .../scope/lifetime/static_lifetime/input.md | 3 + .../static_lifetime/static_lifetime.rs | 13 +++ examples/scope/lifetime/struct/input.md | 9 ++- examples/scope/lifetime/struct/struct.rs | 52 ++++++------ examples/structure.json | 8 +- 21 files changed, 317 insertions(+), 203 deletions(-) delete mode 100644 examples/scope/lifetime/borrow/borrow.rs delete mode 100644 examples/scope/lifetime/borrow/input.md create mode 100644 examples/scope/lifetime/elision/elision.rs create mode 100644 examples/scope/lifetime/elision/input.md create mode 100644 examples/scope/lifetime/lifetime.rs create mode 100644 examples/scope/lifetime/lifetime_bounds/bounds.rs create mode 100644 examples/scope/lifetime/lifetime_bounds/input.md create mode 100644 examples/scope/lifetime/lifetime_coercion/coercion.rs create mode 100644 examples/scope/lifetime/lifetime_coercion/input.md create mode 100644 examples/scope/lifetime/methods/input.md create mode 100644 examples/scope/lifetime/methods/methods.rs diff --git a/examples/scope/lifetime/borrow/borrow.rs b/examples/scope/lifetime/borrow/borrow.rs deleted file mode 100644 index 006f12ac97..0000000000 --- a/examples/scope/lifetime/borrow/borrow.rs +++ /dev/null @@ -1,19 +0,0 @@ -// FIXME To see the "real" compiler error, change both `&'c` and `&'d` into `&` - -fn main() { // `'main` starts ────────────────────────────────────────────┐ - let stack_integer: i32 = 5; // `'a` starts ─────────────────────────┐ │ - let boxed_integer = Box::new(4); // `'b` starts ──────────────────┐ │ │ - // │ │ │ - // This is a valid operation │ │ │ - let ref_to_box: &'c i32 = &*boxed_integer; // `'c` starts ──────┐ │ │ │ - // │ │ │ │ - // The compiler forbids this operation, because │ │ │ │ - // `ref_to_another_box` would become a dangling pointer │ │ │ │ - let ref_to_another_box: &'d i32 = { // `'let` `'d` start ───┬─┐ │ │ │ │ - let another_boxed_integer = Box::new(3); // ──────────┐ │ │ │ │ │ │ - // ^ `e` starts │ │ │ │ │ │ │ - &*another_boxed_integer // │ │ │ │ │ │ │ - }; // `'e` `'let` end ────────────────────────────────────┴─┘ │ │ │ │ │ - // │ │ │ │ │ - let invalid_dereference = *ref_to_another_box; // │ │ │ │ │ -} // `'d` `'c` `'b` `'a` `'main` end ─────────────────────────────┴─┴─┴─┴─┘ diff --git a/examples/scope/lifetime/borrow/input.md b/examples/scope/lifetime/borrow/input.md deleted file mode 100644 index a6bb60d69c..0000000000 --- a/examples/scope/lifetime/borrow/input.md +++ /dev/null @@ -1,53 +0,0 @@ -Let's see how the compiler prevents the creation of dangling pointers via its -borrow checker. To simplify the analysis and explanation, we have two -additions: - -* Lifetimes has been explicitly annotated in the source code. -* We have drawn the lifetime "lines", which span from the creation of an object - to its destruction. The block scopes have also been drawn. - -Note that explicit lifetime annotation on references `&'foo T` is not allowed -by the compiler, so you must remove the lifetime part `'foo` to see the "real" -compiler error. - -{borrow.play} - -The "real" compiler error is: "`another_boxed_integer` does not live long -enough". Let's analyze why this happens: - -* `stack_integer` has lifetime `'a` -* `boxed_integer` has lifetime `'b` -* `ref_to_box` has lifetime `'c` -* `ref_to_another_box` has lifetime `'d` -* `another_boxed_integer` has lifetime `'e` -* `'main` and `'let` are the scopes of the blocks -* When a block scope ends, all the objects declared in it get destroyed - * `'let` ends, and so does `'e` - * `'main` ends, and so do `'a` `'b` `'c` and `'d` -* `ref_to_box` is a valid borrow, because - * `ref_to_box` has lifetime `'c` - * `ref_to_box` points to an object with lifetime `'b` - * `'c` will never *outlive* `'b` (this is expressed as `'c < 'b`) - * therefore `ref_to_box` will always point to valid data -* `ref_to_another_box` is an *invalid* borrow, because - * `ref_to_another_box` has lifetime `'d` - * `ref_to_another_box` points to an object with lifetime `'e` - * `'d` outlives `'e` - * therefore `ref_to_another_box` can become a dangling pointer (it can point - to destroyed data) - * creation of dangling pointers is forbidden, so this borrow is invalid - -The borrow checker will do this job for the programmer behind his/her back, to -prevent him/her from (unintentionally) creating dangling pointers. Although, -the programmer can be saved by the borrow checker without knowing what a -lifetime is. - -The programmer doesn't need to explicitly annotate lifetimes (nor understand -what are lifetimes), for the borrow checker to do its job in most cases. These -are the cases where explicit lifetimes are required: - -* [Functions that return references][lifetime] -* [Structs that hold references][structs] - -[lifetime]: /scope/lifetime/fn.html -[structs]: /scope/lifetime/struct.html diff --git a/examples/scope/lifetime/elision/elision.rs b/examples/scope/lifetime/elision/elision.rs new file mode 100644 index 0000000000..7bbbec60f9 --- /dev/null +++ b/examples/scope/lifetime/elision/elision.rs @@ -0,0 +1,23 @@ +// These two functions have essentially identical signatures +// because the compiler implicitly adds the lifetimes to +// the first. +fn elide_input(x: &i32) { + println!("`elide_input`: {}", x) +} +fn annotated_input<'a>(x: &'a i32) { + println!("`annotated_input`: {}", x) +} + +// Similarly, lifetimes are added implicitly to the first. +fn elide_pass(x: &i32) -> &i32 { x } +fn annotated_pass<'a>(x: &'a i32) -> &'a i32 { x } + +fn main() { + let x = 3; + + elide_input(&x); + annotated_input(&x); + + println!("`elide_pass`: {}", elide_pass(&x)); + println!("`annotated_pass`: {}", annotated_pass(&x)); +} diff --git a/examples/scope/lifetime/elision/input.md b/examples/scope/lifetime/elision/input.md new file mode 100644 index 0000000000..df44875db1 --- /dev/null +++ b/examples/scope/lifetime/elision/input.md @@ -0,0 +1,14 @@ +Some lifetime patterns are overwelmingly common and so they may be elide +(dropped) and the borrow checker will implicitly add them. Elision exists +solely because these patterns are common; saving typing and easing legibility. + +This section is brief and not comprehensive. See [lifetime elision][elision] +in the book for a more comprehensive treatment. + +{elision.play} + +### See also: + +[elision][elision] + +[elision]: http://doc.rust-lang.org/book/lifetimes.html#lifetime-elision diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index 04f7529819..45a790e0fa 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -1,24 +1,34 @@ -struct Book { - // `String` is a heap allocated string - title: String, - author: String, - year: i32, +// `print_refs` takes two references to `i32` which have different +// lifetimes `'a` and `'b`. These two lifetimes must both outlive +// the function `print_refs`. +fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { + println!("x is {} and y is {}", x, y); + + // Suppose this `drop` worked. Then `print_refs` would outlive + // `x` and `four` from `main()` would refer to erased data. + // These two things go hand in hand and so both are banned. + // + //drop(*x); + // ERROR: cannot move out of borrowed content } -fn get_title<'a>(book: &'a Book) -> &'a str { - &book.title +// `failed_borrow` takes no references and returns nothing but has +// a single lifetime `'a` which must outlive the function. +fn failed_borrow<'a>() { + let _x = 12; + + // Attempting to use the lifetime `'a` as an explicit type + // annotation inside the function will fail because the + // lifetime `'a` doesn't match the lifetime that `y` has. + // `y` starts inside `failed_borrow` and so it is smaller. + // + //let y: &'a i32 = &_x; + // ERROR: `_x` does not live long enough } fn main() { - let geb = Book { - // construct a `String` from a reference to a string (`&'static str`) - // by copying of the data - author: "Douglas Hofstadter".to_string(), - title: "Godel, Escher, Bach".to_string(), - year: 1979, - }; - - let title: &str = get_title(&geb); + let (four, nine) = (4, 9); - println!("I just read {}", title); + print_refs(&four, &nine); + failed_borrow(); } diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index 7ad7450754..26dbd4dd94 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -1,16 +1,30 @@ -When writing functions that return references, lifetimes must be explicitly -annotated. These functions are generic and we must tell the compiler what is -the relationship between the lifetimes of the objects that appear in the -arguments and the output. +The borrow checker utilizes explicit lifetime annotation to reason about +how long references should be valid. Failure to annotate lifetimes[^1] is akin +to banning the borrow checker from validating borrows and so accordingly, +annotation is mandatory. -Let's illustrate with an example: we want a function that returns a reference -to the title field of a Book struct. The most generic function that we could -write would look like this: +Since lifetimes *currently* have no explicit type or name associated with them, +usage will require generics (similar to [closures][anonymity]). Somewhat +peculiarly, lifetime annotation has a second additional meaning. `foo<'a, 'b>` +states: + +1. `'a` and `'b` will represent names for lifetimes with non-specifiable +(generic) types. +2. The lifetime of `foo` may not exceed either lifetimes `'a` or `'b`. + +Explicit annotation of a type has the form: `&'a T` where `'a` has already +been introduced. {explicit.play} -The compiler can't tell how `'a` and `'b` are related, so we must supply this -information. The answer here is that `'a = 'b`, the reason is that the title -field will be destroyed when the book gets destroyed (same way with the -creation time), therefore the title field has the same lifetime as the book. +[^1]: [elision][elision] implicitly annotates lifetimes and so is different. + +### See also: + +[generics][generics] and [closures][closures] + +[anonymity]: /fn/closures/anonymity.html +[closures]: /fn/closures.html +[elision]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +[generics]: /generics.html diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index 130d6f7a5a..c97c5b1189 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -1,50 +1,46 @@ -#[derive(Debug)] -struct Triplet { - one: i32, - two: i32, - three: i32, +// One input reference with lifetime `'a` which must live +// longer than the function. This restricts the function +// from ever being able to consume the input. +fn print_one<'a>(x: &'a i32) { + println!("`print_one`: x is {}", x); } -impl Triplet { - // First attempt: No explicit lifetimes - // The compiler infers that the field and the struct have the same lifetime - fn mut_one(&mut self) -> &mut i32 { - &mut self.one - } - - // Second attempt: We explicitly annotate the lifetimes on all the - // references - // Error! The compiler doesn't know what is the relationship between the - // lifetime `structure` and the lifetime `field` - //fn mut_two<'structure, 'field>(&'structure mut self) -> &'field mut i32 { - //&mut self.two - //} - // TODO ^ Try uncommenting this method - - // Third attempt: We think! What is the relationship between the lifetimes? - // Clearly `'field` *can't* outlive `'structure`, because the field will be - // destroyed when the struct gets destroyed - // If the fields get destroyed along with the struct, then that means that - // both the struct and its field have the same lifetime! - // Ok, so we need to tell the compiler that `'structure` = `'field` - // We can use a shorter name for the lifetime, it's common to use a single - // letter lifetime, let's use `'s`, because it's the first letter of - // structure - fn mut_three<'s>(&'s mut self) -> &'s mut i32 { - &mut self.three - } +// Mutable references are possible with lifetimes as well. +fn add_one<'a>(x: &'a mut i32) { + *x += 1; } -fn main() { - let mut triplet = Triplet { one: 1, two: 2, three: 3 }; - - println!("Before: {:?}", triplet); +// Multiple elements with different lifetimes. This would +// be equally acceptable if both references had the same +// lifetime `'a`. +fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { + println!("`print_multi`: x is {}, y is {}", x, y); +} - *triplet.mut_one() = 0; - println!("After: {:?}", triplet); +// This is invalid. An `i32` would be created, a reference +// would be created, then immediately the data would be +// dropped leaving a reference to invalid data to be returned. +// +// The reason the problem is caught is because of the restriction +// `<'a>` imposes: `'a` must live longer than the function. +//fn invalid_output<'a>() -> &'a i32 { &7 } - // Use mutable reference to modify the original struct - *triplet.mut_three() = 0; +// While returning references without input is banned, returning +// references that have been passed in are perfectly acceptable. +// One restriction is the correct lifetime must be returned. +fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } - println!("After: {:?}", triplet); +fn main() { + let x = 7; + let y = 9; + + print_one(&x); + print_multi(&x, &y); + + let z = pass_x(&x, &y); + print_one(z); + + let mut t = 3; + add_one(&mut t); + print_one(&t); } diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md index 991080c362..79b4a1338f 100644 --- a/examples/scope/lifetime/fn/input.md +++ b/examples/scope/lifetime/fn/input.md @@ -1,4 +1,15 @@ -Explicit lifetimes are necessary when functions return references. Our case -study will be returning a reference to one of the fields of a struct. +Functions with lifetimes have a few different valid forms. Ignoring +[elision][elision] for the time being, the rules for function parameters are: + +* any reference *must* have an annotated lifetime. +* any reference being returned *must* have the same lifetime as an input. {fn.play} + +### See also: + +[functions][fn] + + +[elision]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +[fn]: /fn.html diff --git a/examples/scope/lifetime/input.md b/examples/scope/lifetime/input.md index 39190cb957..fb6b38c597 100644 --- a/examples/scope/lifetime/input.md +++ b/examples/scope/lifetime/input.md @@ -1,33 +1,13 @@ -The compiler enforces valid borrowing using its borrow checker. To accomplish -this, it keeps track of the scope of blocks. +A *lifetime* is a construct the compiler (also called the borrow checker) +uses to ensure all borrows are valid. Specifically, the lifetime refers to +the span which starts when the variable is created and ends when the variable +is destroyed. Borrowing (via `&` for example) also creates new lifetimes. -The lifetime of an object starts when the object is created and ends when it -goes out of scope (i.e. it gets destroyed, because of the RAII discipline). +A borrow is valid as long as the borrow ends before (inside) the lender is +destroyed. As you can see below, the lifetime of a variable is directly related +to the scope in which it was created: -A lifetime looks like this: `'burrito`, which reads as: "the lifetime burrito". +{lifetime.play} -All references actually have a type signature of the form `&'a T`, where -`'a` is the lifetime of the *referenced* object. The compiler takes care of -inserting the lifetime part `'a` so we can simply type annotate references with -`&T`. - -For example: - -```rust -let integer: int = 5; -let ref_to_int: &int = &integer; -``` - -* `integer` has lifetime `'i` (it could be any other name, like `'foo`) -* `ref_to_int` has lifetime `'r` (references also have lifetimes!) -* `ref_to_int` type signature actually is `&'i int` (the compiler inserts the - `'i` for us) -* The type signature `&'i int` reads as: - * `&`: reference to an - * `int`: integer with - * `'i`: lifetime `i` (`i` is the lifetime of `integer`!) - -Because the compiler keeps track of the lifetime of referenced objects in the -type system, it can avoid several memory bugs. - -Haven't grokked what a lifetime is yet? Don't dismay! See the next page. +You may have noted that no names or types are assigned to label lifetimes. +This restricts how lifetimes will be able to be used as we will see. diff --git a/examples/scope/lifetime/lifetime.rs b/examples/scope/lifetime/lifetime.rs new file mode 100644 index 0000000000..ebe24c76cd --- /dev/null +++ b/examples/scope/lifetime/lifetime.rs @@ -0,0 +1,12 @@ +// Lifetimes are annotated with a lines denoting +// when each variable is created and destroyed: +fn main() { + let i = 3; // Lifetime for `i` starts. ───────┐ + // │ + { // │ + let borrow = &i; // Borrow starts. ──────┐│ + // ││ + println!("Borrowed `i`: {}", borrow); // ││ + } // Borrow ends. ───────────────────────────┘│ + // │ +} // Lifetime ends. ────────────────────────────┘ diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs new file mode 100644 index 0000000000..306c0fff4f --- /dev/null +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -0,0 +1,30 @@ +use std::fmt::Debug; // Trait to bound with. + +#[derive(Debug)] +// `Ref` contains a reference to type `T` where `T` is unknown +// with an unknown lifetime `'a`. `T` is bounded such that any +// references in `T` must outlive `'a`. In addition, the +// lifetime of `Ref` may not exceed `'a`. +struct Ref<'a, T: 'a>(&'a T); + +// A generic function which prints using the `Debug` trait. +fn print(t: T) where + T: Debug { + println!("`print`: t is {:?}", t); +} + +// Here a reference to `T` is taken where `T` implements +// `Debug` and *all* references in `T` outlive `'a`. In +// addition, `'a` must outlive the function. +fn print_ref<'a, T>(t: &'a T) where + T: Debug + 'a { + println!("`print_ref`: t is {:?}", t); +} + +fn main() { + let x = 7; + let ref_x = Ref(&x); + + print_ref(&ref_x); + print(ref_x); +} diff --git a/examples/scope/lifetime/lifetime_bounds/input.md b/examples/scope/lifetime/lifetime_bounds/input.md new file mode 100644 index 0000000000..0cec71b712 --- /dev/null +++ b/examples/scope/lifetime/lifetime_bounds/input.md @@ -0,0 +1,17 @@ +Just like generic types can be bounded, lifetimes as generics themselves +utilize bounds also, differences notwithstanding. `:` has a slightly +different meaning than in [generics][bounds] but `+` hasn't changed. Both +are described below: + +1. `T: 'a`: *All* references in `T` must outlive lifetime `'a`. +2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references +in `T` must outlive `'a`. + +{bounds.play} + +### See also: + +[generics][generics] and [bounds in generics][bounds] + +[generics]: /generics.html +[bounds]: /generics/bounds.html diff --git a/examples/scope/lifetime/lifetime_coercion/coercion.rs b/examples/scope/lifetime/lifetime_coercion/coercion.rs new file mode 100644 index 0000000000..7fe383cc36 --- /dev/null +++ b/examples/scope/lifetime/lifetime_coercion/coercion.rs @@ -0,0 +1,21 @@ +// `x` is a reference with lifetime `'a` which is larger than `'b`. +// Both `'a` and `'b` are larger than `coerce_first`. Since `'a` is +// larger than `'b`, it may be coerced. +fn coerce_first<'a: 'b, 'b>(x: &'a i32, _: &'b i32) -> &'b i32 { + x +} + +fn main() { + let x = 3; + let y = 4; + + let borrow_big = &x; + { + // This reference is inside a scope and therefore is + // smaller than the other borrow. + let borrow_small = &y; + + let coerced = coerce_first(borrow_big, borrow_small); + println!("`coerced` is {}", coerced); + } +} diff --git a/examples/scope/lifetime/lifetime_coercion/input.md b/examples/scope/lifetime/lifetime_coercion/input.md new file mode 100644 index 0000000000..5212727897 --- /dev/null +++ b/examples/scope/lifetime/lifetime_coercion/input.md @@ -0,0 +1,4 @@ +A lifetime may be coerced into another if the the original is larger than +the new lifetime: + +{coercion.play} diff --git a/examples/scope/lifetime/methods/input.md b/examples/scope/lifetime/methods/input.md new file mode 100644 index 0000000000..ffb8279b02 --- /dev/null +++ b/examples/scope/lifetime/methods/input.md @@ -0,0 +1,10 @@ +Methods are annotated similarly to functions: + +{methods.play} + +### See also: + +[methods][methods] + + +[methods]: /fn/methods.html diff --git a/examples/scope/lifetime/methods/methods.rs b/examples/scope/lifetime/methods/methods.rs new file mode 100644 index 0000000000..faa47ff0ce --- /dev/null +++ b/examples/scope/lifetime/methods/methods.rs @@ -0,0 +1,17 @@ +// A regular structure. +struct Owner(i32); + +impl Owner { + // Annotate exactly like a normal function. + fn add_one<'a>(&'a mut self) { self.0 += 1 } + fn print<'a>(&'a self) { + println!("`print`: {}", self.0); + } +} + +fn main() { + let mut owner = Owner(18); + + owner.add_one(); + owner.print(); +} diff --git a/examples/scope/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md index ac0e12198e..535a12318d 100644 --- a/examples/scope/lifetime/static_lifetime/input.md +++ b/examples/scope/lifetime/static_lifetime/input.md @@ -4,6 +4,9 @@ program. There are two ways to make a variable with `'static` lifetime: * Make a `"string"` literal which has type: `&'static str`. * Make a constant with the `static` declaration. +`statics` may also be coerced to smaller lifetimes since they are clearly +larger than most: + {static_lifetime.play} ### See also: diff --git a/examples/scope/lifetime/static_lifetime/static_lifetime.rs b/examples/scope/lifetime/static_lifetime/static_lifetime.rs index bd34d5ea0a..aaf0f965f8 100644 --- a/examples/scope/lifetime/static_lifetime/static_lifetime.rs +++ b/examples/scope/lifetime/static_lifetime/static_lifetime.rs @@ -1,5 +1,11 @@ static NUM: i32 = 18; +// Return a reference to `NUM` which is coerced to the +// lifetime of `'a` which was used as an input. +fn coerce_static<'a>(_: &'a i32) -> &'a i32 { + &NUM +} + fn main() { { // String literals are references to read-only memory @@ -12,4 +18,11 @@ fn main() { println!("but now it's gone."); println!("NUM: {} is still around though!", NUM); + + { + let i = 9; + let coerced_num = coerce_static(&i); + + println!("coerced_num: {}", coerced_num); + } } diff --git a/examples/scope/lifetime/struct/input.md b/examples/scope/lifetime/struct/input.md index a8fe7a8a4f..496e989f9f 100644 --- a/examples/scope/lifetime/struct/input.md +++ b/examples/scope/lifetime/struct/input.md @@ -1,3 +1,10 @@ -Explicit lifetimes are also required in structs that hold references. +Annotation of lifetimes in structures are also similar to functions: {struct.play} + +### See also: + +[`structs`][structs] + + +[structs]: /custom_types/structs.html diff --git a/examples/scope/lifetime/struct/struct.rs b/examples/scope/lifetime/struct/struct.rs index 83108ba99b..abdfcec241 100644 --- a/examples/scope/lifetime/struct/struct.rs +++ b/examples/scope/lifetime/struct/struct.rs @@ -1,33 +1,33 @@ -// First attempt: No explicit lifetimes -// Error! Compiler needs explicit lifetime -//struct Singleton { - //one: &mut i32, -//} -// TODO ^ Try uncommenting this struct +// A type `Borrowed` which houses a reference to an +// `i32`. This reference must outlive the structure. +#[derive(Debug)] +struct Borrowed<'a>(&'a i32); -// Second attempt: Add lifetimes to all the references -struct Pair<'a, 'b> { - one: &'a mut i32, - two: &'b mut i32, +// Similarly, both references must outlive this structure. +#[derive(Debug)] +struct NamedBorrowed<'a> { + x: &'a i32, + y: &'a i32, } -fn main() { - // Let us say that `one` has lifetime `o` - let mut one = 1; - - { - // And that `two` has lifetime `t` - // `two` has a shorter (and different) lifetime than `one` (`'t < 'o`) - let mut two = 2; - - println!("Before: ({}, {})", one, two); +// An enum which is either an `i32` or a reference to one. +#[derive(Debug)] +enum Either<'a> { + Num(i32), + Ref(&'a i32), +} - // `Pair` gets specialized for `'a = 'o` and `'b = 't` - let pair = Pair { one: &mut one, two: &mut two }; +fn main() { + let x = 18; + let y = 15; - *pair.one = 2; - *pair.two = 1; + let single = Borrowed(&x); + let double = NamedBorrowed { x: &x, y: &y }; + let reference = Either::Ref(&x); + let number = Either::Num(y); - println!("After: ({}, {})", pair.one, pair.two); - } + println!("x is borrowed in {:?}", single); + println!("x and y are borrowed in {:?}", double); + println!("x is borrowed in {:?}", reference); + println!("y is *not* borrowed in {:?}", number); } diff --git a/examples/structure.json b/examples/structure.json index 9753e708b3..c0e00640fa 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -125,10 +125,14 @@ { "id": "ref", "title": "The ref pattern", "children": null } ] }, { "id": "lifetime", "title": "Lifetimes", "children": [ - { "id": "borrow", "title": "The borrow checker", "children": null }, + { "id": "explicit", "title": "Explicit annotation", "children": null }, { "id": "fn", "title": "Functions", "children": null }, + { "id": "methods", "title": "Methods", "children": null }, { "id": "struct", "title": "Structs", "children": null }, - { "id": "static_lifetime", "title": "static", "children": null } + { "id": "lifetime_bounds", "title": "Bounds", "children": null }, + { "id": "lifetime_coercion", "title": "Coercion", "children": null }, + { "id": "static_lifetime", "title": "static", "children": null }, + { "id": "elision", "title": "elision", "children": null } ] } ] }, { "id": "trait", "title": "Traits", "children": [ From 1c69d79a4ed7566b07a654d977064427d4eb75f1 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 9 Jul 2015 14:53:05 -0400 Subject: [PATCH 0323/1122] Many slight lifetime tweaks --- examples/scope/lifetime/elision/input.md | 2 +- examples/scope/lifetime/explicit/explicit.rs | 11 ++-------- examples/scope/lifetime/explicit/input.md | 8 ++++++-- examples/scope/lifetime/fn/input.md | 2 +- examples/scope/lifetime/input.md | 12 +++++------ examples/scope/lifetime/lifetime.rs | 20 ++++++++++++++----- .../scope/lifetime/lifetime_bounds/bounds.rs | 5 +++-- .../scope/lifetime/lifetime_bounds/input.md | 5 ++--- .../lifetime/lifetime_coercion/coercion.rs | 4 ++-- 9 files changed, 38 insertions(+), 31 deletions(-) diff --git a/examples/scope/lifetime/elision/input.md b/examples/scope/lifetime/elision/input.md index df44875db1..9bfa9c6115 100644 --- a/examples/scope/lifetime/elision/input.md +++ b/examples/scope/lifetime/elision/input.md @@ -1,4 +1,4 @@ -Some lifetime patterns are overwelmingly common and so they may be elide +Some lifetime patterns are overwelmingly common and so they may be elided (dropped) and the borrow checker will implicitly add them. Elision exists solely because these patterns are common; saving typing and easing legibility. diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index 45a790e0fa..59685c8a07 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -1,15 +1,8 @@ // `print_refs` takes two references to `i32` which have different -// lifetimes `'a` and `'b`. These two lifetimes must both outlive -// the function `print_refs`. +// lifetimes `'a` and `'b`. These two lifetimes must both be at +// least as long as the function `print_refs`. fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { println!("x is {} and y is {}", x, y); - - // Suppose this `drop` worked. Then `print_refs` would outlive - // `x` and `four` from `main()` would refer to erased data. - // These two things go hand in hand and so both are banned. - // - //drop(*x); - // ERROR: cannot move out of borrowed content } // `failed_borrow` takes no references and returns nothing but has diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index 26dbd4dd94..09247de178 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -13,7 +13,11 @@ states: 2. The lifetime of `foo` may not exceed either lifetimes `'a` or `'b`. Explicit annotation of a type has the form: `&'a T` where `'a` has already -been introduced. +been introduced. Together with **Rule 2**, this specifies that any borrow +*must* eventually be returned. That is, if a function/type borrows a +reference, when the borrower ceases, the reference must be returned *or* the +borrow would be invalid! Borrowing and never returning cannot really be called +borrowing. {explicit.play} @@ -26,5 +30,5 @@ been introduced. [anonymity]: /fn/closures/anonymity.html [closures]: /fn/closures.html -[elision]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +[elision]: /scope/lifetime/elision.html [generics]: /generics.html diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md index 79b4a1338f..1095c32790 100644 --- a/examples/scope/lifetime/fn/input.md +++ b/examples/scope/lifetime/fn/input.md @@ -11,5 +11,5 @@ Functions with lifetimes have a few different valid forms. Ignoring [functions][fn] -[elision]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +[elision]: /scope/lifetime/elision.html [fn]: /fn.html diff --git a/examples/scope/lifetime/input.md b/examples/scope/lifetime/input.md index fb6b38c597..abb0316a2c 100644 --- a/examples/scope/lifetime/input.md +++ b/examples/scope/lifetime/input.md @@ -1,11 +1,11 @@ A *lifetime* is a construct the compiler (also called the borrow checker) -uses to ensure all borrows are valid. Specifically, the lifetime refers to -the span which starts when the variable is created and ends when the variable -is destroyed. Borrowing (via `&` for example) also creates new lifetimes. +uses to ensure all borrows are valid. Specifically, a lifetime starts when +a variable is created and ends when it is destroyed. It can be visualized as +vertical distance but since size is only relevant for subsets and supersets, +scope is considered the more appropriate descriptive term. -A borrow is valid as long as the borrow ends before (inside) the lender is -destroyed. As you can see below, the lifetime of a variable is directly related -to the scope in which it was created: +Borrowing (via `&` for example) creates new lifetimes. A borrow is valid +as long as the borrow ends before (inside) the lender is destroyed. {lifetime.play} diff --git a/examples/scope/lifetime/lifetime.rs b/examples/scope/lifetime/lifetime.rs index ebe24c76cd..d2d2df4eef 100644 --- a/examples/scope/lifetime/lifetime.rs +++ b/examples/scope/lifetime/lifetime.rs @@ -1,12 +1,22 @@ -// Lifetimes are annotated with a lines denoting -// when each variable is created and destroyed: +// Lifetimes are annotated with lines denoting when each variable +// is created and destroyed. `i` has the largest lifetime because it's +// scope entirely encloses both `borrow1` and `borrow2`. The sizedness +// of `borrow1` compared with `borrow2` is irrelevant since they are +// disjoint. fn main() { let i = 3; // Lifetime for `i` starts. ───────┐ // │ { // │ - let borrow = &i; // Borrow starts. ──────┐│ + let borrow1 = &i; // `borrow1` starts. ──┐│ // ││ - println!("Borrowed `i`: {}", borrow); // ││ - } // Borrow ends. ───────────────────────────┘│ + println!("borrow1: {}", borrow1); // ││ + } // `borrow1 ends. ─────────────────────────┘│ + // │ + // │ + { // │ + let borrow2 = &i; // `borrow2` starts. ──┐│ + // ││ + println!("borrow2: {}", borrow2); // ││ + } // `borrow2` ends. ────────────────────────┘│ // │ } // Lifetime ends. ────────────────────────────┘ diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs index 306c0fff4f..21d2c54474 100644 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -3,8 +3,9 @@ use std::fmt::Debug; // Trait to bound with. #[derive(Debug)] // `Ref` contains a reference to type `T` where `T` is unknown // with an unknown lifetime `'a`. `T` is bounded such that any -// references in `T` must outlive `'a`. In addition, the -// lifetime of `Ref` may not exceed `'a`. +// references in `T` must outlive `'a` (a borrow from `T` must +// be returned so `T` may return it to it's rightful owner). +// In addition, the lifetime of `Ref` may not exceed `'a`. struct Ref<'a, T: 'a>(&'a T); // A generic function which prints using the `Debug` trait. diff --git a/examples/scope/lifetime/lifetime_bounds/input.md b/examples/scope/lifetime/lifetime_bounds/input.md index 0cec71b712..9ea237f770 100644 --- a/examples/scope/lifetime/lifetime_bounds/input.md +++ b/examples/scope/lifetime/lifetime_bounds/input.md @@ -1,7 +1,6 @@ Just like generic types can be bounded, lifetimes as generics themselves -utilize bounds also, differences notwithstanding. `:` has a slightly -different meaning than in [generics][bounds] but `+` hasn't changed. Both -are described below: +utilize bounds also. `:` has a slightly different meaning than in +[generics][bounds] but `+` hasn't changed. Both are described below: 1. `T: 'a`: *All* references in `T` must outlive lifetime `'a`. 2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references diff --git a/examples/scope/lifetime/lifetime_coercion/coercion.rs b/examples/scope/lifetime/lifetime_coercion/coercion.rs index 7fe383cc36..377cfea17e 100644 --- a/examples/scope/lifetime/lifetime_coercion/coercion.rs +++ b/examples/scope/lifetime/lifetime_coercion/coercion.rs @@ -6,8 +6,8 @@ fn coerce_first<'a: 'b, 'b>(x: &'a i32, _: &'b i32) -> &'b i32 { } fn main() { - let x = 3; - let y = 4; + let x = 800; + let y = 8; let borrow_big = &x; { From 2f01a630657db8d5ce8b6a5241ada2ac4ed5508c Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 10 Jul 2015 17:14:05 -0400 Subject: [PATCH 0324/1122] Additional lifetime tweaks --- examples/scope/lifetime/explicit/explicit.rs | 36 +++++++++++++------ examples/scope/lifetime/explicit/input.md | 12 +++---- examples/scope/lifetime/fn/fn.rs | 3 +- .../scope/lifetime/lifetime_bounds/bounds.rs | 5 ++- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index 59685c8a07..c683a7afaa 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -1,3 +1,24 @@ +// This example uses `main()` at the top so it can be read top to +// bottom. `main()` is usually at the bottom. +fn main() { + // Create variables which will be borrowed. + let (four, nine) = (4, 9); + + // Borrows (`&`) of both variables are passed into the function. + // If a borrow is truly a borrow, the variable must be returned, + // otherwise a borrow would be transferring ownership. This means + // no matter what, *any* input which is borrowed via function or + // otherwise, *must* still exist after the borrower ceases. In + // other words, *Rule 2* must be true. + print_refs(&four, &nine); + + // Uses a lifetime without any input. The lifetime sizedness will + // be chosen by the caller (which is here) from available lifetimes + // (scopes). Any lifetime chosen will then be larger than that of + // the function. + failed_borrow(); +} + // `print_refs` takes two references to `i32` which have different // lifetimes `'a` and `'b`. These two lifetimes must both be at // least as long as the function `print_refs`. @@ -5,23 +26,16 @@ fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { println!("x is {} and y is {}", x, y); } -// `failed_borrow` takes no references and returns nothing but has -// a single lifetime `'a` which must outlive the function. +// There are no references to force `'a` to be larger than the +// function yet, `'a` remains larger than the function. fn failed_borrow<'a>() { let _x = 12; // Attempting to use the lifetime `'a` as an explicit type // annotation inside the function will fail because the - // lifetime `'a` doesn't match the lifetime that `y` has. - // `y` starts inside `failed_borrow` and so it is smaller. + // lifetime of `&_x` is smaller than `y` has. A small lifetime + // cannot be coerced into a larger one. // //let y: &'a i32 = &_x; // ERROR: `_x` does not live long enough } - -fn main() { - let (four, nine) = (4, 9); - - print_refs(&four, &nine); - failed_borrow(); -} diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index 09247de178..f88403da2e 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -4,8 +4,8 @@ to banning the borrow checker from validating borrows and so accordingly, annotation is mandatory. Since lifetimes *currently* have no explicit type or name associated with them, -usage will require generics (similar to [closures][anonymity]). Somewhat -peculiarly, lifetime annotation has a second additional meaning. `foo<'a, 'b>` +usage will require generics (similar to [closures][anonymity]). Additionally, +a second meaning will be associated with this lifetime syntax. `foo<'a, 'b>` states: 1. `'a` and `'b` will represent names for lifetimes with non-specifiable @@ -13,11 +13,9 @@ states: 2. The lifetime of `foo` may not exceed either lifetimes `'a` or `'b`. Explicit annotation of a type has the form: `&'a T` where `'a` has already -been introduced. Together with **Rule 2**, this specifies that any borrow -*must* eventually be returned. That is, if a function/type borrows a -reference, when the borrower ceases, the reference must be returned *or* the -borrow would be invalid! Borrowing and never returning cannot really be called -borrowing. +been introduced. The less obvious of the rules is **Rule 2** whose +importance can usually be directly deduced from borrowing rules. Consider the +following example: {explicit.play} diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index c97c5b1189..51459aa5c6 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -1,6 +1,5 @@ // One input reference with lifetime `'a` which must live -// longer than the function. This restricts the function -// from ever being able to consume the input. +// longer than the function. fn print_one<'a>(x: &'a i32) { println!("`print_one`: x is {}", x); } diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs index 21d2c54474..d0b88df165 100644 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -3,9 +3,8 @@ use std::fmt::Debug; // Trait to bound with. #[derive(Debug)] // `Ref` contains a reference to type `T` where `T` is unknown // with an unknown lifetime `'a`. `T` is bounded such that any -// references in `T` must outlive `'a` (a borrow from `T` must -// be returned so `T` may return it to it's rightful owner). -// In addition, the lifetime of `Ref` may not exceed `'a`. +// references in `T` must outlive `'a`. In addition, the lifetime +// of `Ref` may not exceed `'a`. struct Ref<'a, T: 'a>(&'a T); // A generic function which prints using the `Debug` trait. From b22ba2eef5c8251fc2d91deafa032c4ff81b0185 Mon Sep 17 00:00:00 2001 From: mdinger Date: Tue, 11 Aug 2015 15:37:28 -0400 Subject: [PATCH 0325/1122] Fix most of steves nits --- examples/scope/lifetime/explicit/input.md | 2 +- examples/scope/lifetime/fn/fn.rs | 8 ++++---- examples/scope/lifetime/fn/input.md | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index f88403da2e..cb46870385 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -1,4 +1,4 @@ -The borrow checker utilizes explicit lifetime annotation to reason about +The borrow checker utilizes explicit lifetime annotations to reason about how long references should be valid. Failure to annotate lifetimes[^1] is akin to banning the borrow checker from validating borrows and so accordingly, annotation is mandatory. diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index 51459aa5c6..29e36850db 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -1,5 +1,5 @@ // One input reference with lifetime `'a` which must live -// longer than the function. +// at least as long as the function. fn print_one<'a>(x: &'a i32) { println!("`print_one`: x is {}", x); } @@ -9,9 +9,9 @@ fn add_one<'a>(x: &'a mut i32) { *x += 1; } -// Multiple elements with different lifetimes. This would -// be equally acceptable if both references had the same -// lifetime `'a`. +// Multiple elements with different lifetimes. In this case, it +// would be fine for both to have the same lifetime `'a`, but +// in more complex cases, different lifetimes may be required. fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { println!("`print_multi`: x is {}, y is {}", x, y); } diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md index 1095c32790..29d1a535fa 100644 --- a/examples/scope/lifetime/fn/input.md +++ b/examples/scope/lifetime/fn/input.md @@ -2,7 +2,8 @@ Functions with lifetimes have a few different valid forms. Ignoring [elision][elision] for the time being, the rules for function parameters are: * any reference *must* have an annotated lifetime. -* any reference being returned *must* have the same lifetime as an input. +* any reference being returned *must* have the same lifetime as an input or +be `static`. {fn.play} From dfce986fd7f81bd5cd822bc0ff654006fb1f6895 Mon Sep 17 00:00:00 2001 From: mdinger Date: Tue, 11 Aug 2015 16:10:50 -0400 Subject: [PATCH 0326/1122] Rephrase explicit lifetime comment --- examples/scope/lifetime/explicit/explicit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index c683a7afaa..488bf9a566 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -12,10 +12,10 @@ fn main() { // other words, *Rule 2* must be true. print_refs(&four, &nine); - // Uses a lifetime without any input. The lifetime sizedness will - // be chosen by the caller (which is here) from available lifetimes - // (scopes). Any lifetime chosen will then be larger than that of - // the function. + // Note that there is no input even though the function specifies + // a lifetime. The sizedness of that lifetime will be determined + // by the caller (which is here) from available lifetimes (scopes). + // Any lifetime chosen will then be larger than that of the function. failed_borrow(); } From bd1ee1350428804e4b473310c17884c35ea1e518 Mon Sep 17 00:00:00 2001 From: Julien Rolland Date: Sat, 15 Aug 2015 21:11:45 +0200 Subject: [PATCH 0327/1122] Add enum variants to cover all cases --- examples/custom_types/enum/enum.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/custom_types/enum/enum.rs b/examples/custom_types/enum/enum.rs index 361f82eb87..e7807749be 100644 --- a/examples/custom_types/enum/enum.rs +++ b/examples/custom_types/enum/enum.rs @@ -36,10 +36,15 @@ fn inspect(p: Person) { fn main() { let person = Person::Height(18); + let danny = Person::Weight(10); // `to_owned()` creates an owned `String` from a string slice. let dave = Person::Info { name: "Dave".to_owned(), height: 72 }; - // ^ TODO: Try changing these to a different variants. + let john = Person::Fat; + let larry = Person::Skinny; inspect(person); + inspect(danny); inspect(dave); + inspect(john); + inspect(larry); } From 8503275aa36d03c84bd489242fa4d3039efce808 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 18:35:09 -0400 Subject: [PATCH 0328/1122] Use the newer travis infrastructure --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0330db292e..cb1186689c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,10 @@ language: node_js - -sudo: true +sudo: false install: - - curl -L https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly --yes + - curl -L https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly --yes --prefix=$PWD --disable-sudo --disable-ldconfig + - export PATH=$PATH:$PWD/bin + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib script: - rustc --version From f2bc6c6437ba1fc820ebd4f8aa827cff9f7ee3c1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 16:52:48 -0400 Subject: [PATCH 0329/1122] Move RBE to stable This commit moves everything to stable Rust. In it, we lose a few things: * FnBox examples * Associated Constants * Benchmark tests * PathExt stuff * SIMD * Inline Assembly These are varying degrees of unfortunate. A better build system might be able to do nightly vs stable builds for the relevant bits in the future. --- .travis.yml | 2 +- README.md | 2 +- examples/README.md | 3 - .../fn/closures/output_parameters/input.md | 30 ------- .../output_parameters/output_parameters.rs | 33 -------- examples/fn/hof/hof.rs | 4 +- .../generics/assoc_items/consts/consts.rs | 40 --------- examples/generics/assoc_items/consts/input.md | 7 -- examples/meta/bench/bench.rs | 55 ------------- examples/meta/bench/input.md | 17 ---- examples/std_misc/arg/matching/match_args.rs | 16 ++-- examples/std_misc/fs/fs.rs | 12 --- examples/std_misc/path/path.rs | 18 ---- examples/std_misc/simd/input.md | 25 ------ examples/std_misc/simd/simd.rs | 17 ---- examples/std_misc/simd/simd_add.rs | 82 ------------------- examples/unsafe/asm.rs | 9 -- .../book/editor.js | 2 +- src/example.rs | 2 +- src/main.rs | 3 - 20 files changed, 13 insertions(+), 366 deletions(-) delete mode 100644 examples/fn/closures/output_parameters/input.md delete mode 100644 examples/fn/closures/output_parameters/output_parameters.rs delete mode 100644 examples/generics/assoc_items/consts/consts.rs delete mode 100644 examples/generics/assoc_items/consts/input.md delete mode 100644 examples/meta/bench/bench.rs delete mode 100644 examples/meta/bench/input.md delete mode 100644 examples/std_misc/simd/input.md delete mode 100644 examples/std_misc/simd/simd.rs delete mode 100644 examples/std_misc/simd/simd_add.rs delete mode 100644 examples/unsafe/asm.rs diff --git a/.travis.yml b/.travis.yml index cb1186689c..3810728b97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js sudo: false install: - - curl -L https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly --yes --prefix=$PWD --disable-sudo --disable-ldconfig + - curl -L https://static.rust-lang.org/rustup.sh | sh -s -- --yes --prefix=$PWD --disable-sudo --disable-ldconfig - export PATH=$PATH:$PWD/bin - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib diff --git a/README.md b/README.md index 209c8cac9f..3f2b8b496c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ See [CONTRIBUTING.md][how-to-contribute]. ### Debian (Ubuntu) prerequisites -Install Rust [nightly](http://www.rust-lang.org/install.html) and +Install [Rust](http://www.rust-lang.org/install.html) and run: ``` diff --git a/examples/README.md b/examples/README.md index de3c3ffc97..839f8b03a9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -11,9 +11,6 @@ for this site][home]. Be sure to have Rust [installed][install] and the [docs][std] at hand, and let's start! -*Note*: Rust by Example uses the latest nightly build. If you're -following along on your computer, make sure to have it installed. - [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html [std]: http://doc.rust-lang.org/std/ diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md deleted file mode 100644 index c650c58099..0000000000 --- a/examples/fn/closures/output_parameters/input.md +++ /dev/null @@ -1,30 +0,0 @@ -Closures as input parameters are possible so returning one should also be -possible. However, returning closure types are problematic because Rust -currently only supports returning concrete (non-generic) types. Anonymous -closure types are, by definition, unknown and so returning a closure is only -possible by making it concrete. This can be done via boxing. - -The valid types for returns are slightly different than before: - -* `Fn`: normal -* `FnMut`: normal -* `FnBox`: equivalent to `FnOnce` but specialized for this application -because `FnOnce` currently(version 1.1.0) interacts badly with the type system. - -Beyond this, the `move` keyword must be used which signals that all captures -occur by value. This is required because any captures by reference would be -dropped as soon as the function exited leaving invalid references in the -closure. - -{output_parameters.play} - -### See also: - -[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], [`FnBox`][fnbox], and -[Generics][generics] - -[box]: /std/box.html -[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html -[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html -[fnbox]: http://doc.rust-lang.org/std/boxed/trait.FnBox.html -[generics]: /generics.html diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs deleted file mode 100644 index 5452cb4f12..0000000000 --- a/examples/fn/closures/output_parameters/output_parameters.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![feature(fnbox)] - -use std::boxed::FnBox; - -// Return a closure taking no inputs and returning nothing -// which implements `FnBox` (capture by value). -fn create_fnbox() -> Box { - let text = "FnBox".to_owned(); - - Box::new(move || println!("This is a: {}", text)) -} - -fn create_fn() -> Box { - let text = "Fn".to_owned(); - - Box::new(move || println!("This is a: {}", text)) -} - -fn create_fnmut() -> Box { - let text = "FnMut".to_owned(); - - Box::new(move || println!("This is a: {}", text)) -} - -fn main() { - let fn_plain = create_fn(); - let mut fn_mut = create_fnmut(); - let fn_box = create_fnbox(); - - fn_plain(); - fn_mut(); - fn_box(); -} diff --git a/examples/fn/hof/hof.rs b/examples/fn/hof/hof.rs index 592cfea45d..a0ce5aaf58 100644 --- a/examples/fn/hof/hof.rs +++ b/examples/fn/hof/hof.rs @@ -1,5 +1,3 @@ -#![feature(iter_arith)] - fn main() { println!("Find the sum of all the squared odd numbers under 1000"); let upper = 1000; @@ -27,7 +25,7 @@ fn main() { (0..).map(|n| n * n) // All natural numbers squared .take_while(|&n| n < upper) // Below upper limit .filter(|n| is_odd(*n)) // That are odd - .sum(); // Sum them + .fold(0, |sum, i| sum + i); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); } diff --git a/examples/generics/assoc_items/consts/consts.rs b/examples/generics/assoc_items/consts/consts.rs deleted file mode 100644 index 49743612e9..0000000000 --- a/examples/generics/assoc_items/consts/consts.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![feature(associated_consts)] - -// 2 null structs. -#[allow(dead_code)] -struct Num; -#[allow(dead_code)] -struct Weird; - -// Trait to define zero. -trait Zero { - // `const` requires a type. Use a default of `0`. - const ZERO: i32 = 0; -} - -// Trait to define one. -trait One { - // Can use the type `Self` which defers to the `impl`. - const ONE: Self; -} - -// Use the default. -impl Zero for Num {} - -// Change the default. -impl Zero for Weird { - const ZERO: i32 = 9; -} - -// Define one for `i32`. -impl One for i32 { - // Type must agree with the `Self` type: `i32`. - const ONE: i32 = 1; -} - -fn main() { - // These calls use the `UFCS` calling syntax. - println!("ZERO for Num is {}", Num::ZERO); // Default. - println!("ZERO for Weird is {}", Weird::ZERO); // Customized. - println!("ONE for i32 is {}", i32::ONE); // Type specified in `impl`. -} diff --git a/examples/generics/assoc_items/consts/input.md b/examples/generics/assoc_items/consts/input.md deleted file mode 100644 index a3bf4b92c3..0000000000 --- a/examples/generics/assoc_items/consts/input.md +++ /dev/null @@ -1,7 +0,0 @@ -`trait`s holding `const`s are called Associated `const`s: - -{consts.play} - -### See also: - -[UFCS RFC](https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md) diff --git a/examples/meta/bench/bench.rs b/examples/meta/bench/bench.rs deleted file mode 100644 index f549587fbf..0000000000 --- a/examples/meta/bench/bench.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![feature(test)] - -extern crate test; - -use std::mem::replace; -use test::Bencher; - -// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence -static BENCH_SIZE: usize = 20; - -// recursive fibonacci -fn fibonacci(n: usize) -> u32 { - if n < 2 { - 1 - } else { - fibonacci(n - 1) + fibonacci(n - 2) - } -} - -// iterative fibonacci -struct Fibonacci { - curr: u32, - next: u32, -} - -impl Iterator for Fibonacci { - type Item = u32; - fn next(&mut self) -> Option { - let new_next = self.curr + self.next; - let new_curr = replace(&mut self.next, new_next); - - Some(replace(&mut self.curr, new_curr)) - } -} - -fn fibonacci_sequence() -> Fibonacci { - Fibonacci { curr: 1, next: 1 } -} - -// function to benchmark must be annotated with `#[bench]` -#[bench] -fn recursive_fibonacci(b: &mut Bencher) { - // exact code to benchmark must be passed as a closure to the iter - // method of Bencher - b.iter(|| { - (0..BENCH_SIZE).map(fibonacci).collect::>() - }) -} - -#[bench] -fn iterative_fibonacci(b: &mut Bencher) { - b.iter(|| { - fibonacci_sequence().take(BENCH_SIZE).collect::>() - }) -} diff --git a/examples/meta/bench/input.md b/examples/meta/bench/input.md deleted file mode 100644 index 20c5e6517c..0000000000 --- a/examples/meta/bench/input.md +++ /dev/null @@ -1,17 +0,0 @@ -Rust provides infrastructure for benchmarking via the `Bencher` struct and -the `#[bench]` attribute. Details in the source code below. - -{bench.rs} - -The source needs to be compiled using the `--test` flag, and the `--bench` flag -must be passed to the resulting binary. - -``` bash -$ rustc --test -O bench.rs -$ ./bench --bench -running 2 tests -test iterative_fibonacci ... bench: 191 ns/iter (+/- 16) -test recursive_fibonacci ... bench: 49670 ns/iter (+/- 522) - -test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured -``` diff --git a/examples/std_misc/arg/matching/match_args.rs b/examples/std_misc/arg/matching/match_args.rs index 6d7abcf458..b77136ad3e 100644 --- a/examples/std_misc/arg/matching/match_args.rs +++ b/examples/std_misc/arg/matching/match_args.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - use std::env; fn increase(number: i32) { @@ -21,21 +19,23 @@ match_args {{increase|decrease}} fn main() { let args: Vec = env::args().collect(); - match &args[..] { + match args.len() { // no arguments passed - [ref name] => { - println!("My name is '{}'. Try passing some arguments!", name); + 1 => { + println!("My name is 'match_args'. Try passing some arguments!"); }, // one argument passed - [_, ref string] => { - if string == &"42" { + 2 => { + if &42 == &args[1].parse().unwrap() { println!("This is the answer!"); } else { println!("This is not the answer."); } }, // one command and one argument passed - [_, ref cmd, ref num] => { + 3 => { + let cmd = &args[1]; + let num = &args[2]; // parse the number let number: i32 = match num.parse() { Ok(n) => { diff --git a/examples/std_misc/fs/fs.rs b/examples/std_misc/fs/fs.rs index 66f6b32c5e..3f7d63cc49 100644 --- a/examples/std_misc/fs/fs.rs +++ b/examples/std_misc/fs/fs.rs @@ -1,5 +1,3 @@ -#![feature(fs_walk)] - use std::fs; use std::fs::{File, OpenOptions}; use std::io; @@ -80,16 +78,6 @@ fn main() { }, } - println!("`walk a`"); - // Recursively walk over the contents of a directory, returns - // `Directories`, which implements the `Iterator trait - match fs::walk_dir("a") { - Err(why) => println!("! {:?}", why.kind()), - Ok(paths) => for path in paths { - println!("> {:?}", path.unwrap().path()); - }, - } - println!("`rm a/c/e.txt`"); // Remove a file, returns `io::Result<()>` fs::remove_file("a/c/e.txt").unwrap_or_else(|why| { diff --git a/examples/std_misc/path/path.rs b/examples/std_misc/path/path.rs index 73c5226053..ab183f10a4 100644 --- a/examples/std_misc/path/path.rs +++ b/examples/std_misc/path/path.rs @@ -1,7 +1,4 @@ -#![feature(path_ext)] - use std::path::Path; -use std::fs::PathExt; fn main() { // Create a `Path` from an `&'static str` @@ -10,21 +7,6 @@ fn main() { // The `display` method returns a `Show`able structure let display = path.display(); - // Check if the path exists - if path.exists() { - println!("{} exists", display); - } - - // Check if the path is a file - if path.is_file() { - println!("{} is a file", display); - } - - // Check if the path is a directory - if path.is_dir() { - println!("{} is a directory", display); - } - // `join` merges a path with a byte container using the OS specific // separator, and returns the new path let new_path = path.join("a").join("b"); diff --git a/examples/std_misc/simd/input.md b/examples/std_misc/simd/input.md deleted file mode 100644 index 312f14886f..0000000000 --- a/examples/std_misc/simd/input.md +++ /dev/null @@ -1,25 +0,0 @@ -Rust provides experimental support for SIMD vectors. These SIMD vectors are -exposed as structs (`f32x4`, `u8x16`, etc.) that implement basic operations -(`+`, `-`, `*`, etc) using SIMD instructions under the hood. - -{simd.rs} - -{simd.out} - -Here's a more complex example that sums two `Vec`, using the `f32x4` type -to operate on 4-element chunks at a time. - -{simd_add.rs} - -And here's the result of the benchmark: - -``` -$ rustc -O --test simd_add.rs && ./simd_add --bench -running 4 tests -test test::simd ... ignored -test test::vanilla ... ignored -test bench::simd ... bench: 1852 ns/iter (+/- 17) -test bench::vanilla ... bench: 8346 ns/iter (+/- 103) - -test result: ok. 0 passed; 0 failed; 2 ignored; 2 measured -``` diff --git a/examples/std_misc/simd/simd.rs b/examples/std_misc/simd/simd.rs deleted file mode 100644 index 144f8f4e5e..0000000000 --- a/examples/std_misc/simd/simd.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(core_simd)] - -use std::simd::f32x4; - -fn main() { - // create simd vectors - let x = f32x4(1.0, 2.0, 3.0, 4.0); - let y = f32x4(4.0, 3.0, 2.0, 1.0); - - // simd product - let z = x * y; - - // like any struct, the simd vector can be destructured using `let` - let f32x4(a, b, c, d) = z; - - println!("{:?}", (a, b, c, d)); -} diff --git a/examples/std_misc/simd/simd_add.rs b/examples/std_misc/simd/simd_add.rs deleted file mode 100644 index 71eeb5863f..0000000000 --- a/examples/std_misc/simd/simd_add.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![feature(test)] -#![feature(core_simd)] - -use std::simd::f32x4; - -macro_rules! assert_equal_len { - ($a:ident, $b: ident) => { - assert!($a.len() == $b.len(), - "add_assign: dimension mismatch: {:?} += {:?}", - ($a.len(),), - ($b.len(),)); - } -} - -// element-wise addition -fn add_assign(xs: &mut Vec, ys: &Vec) { - assert_equal_len!(xs, ys); - - for (x, y) in xs.iter_mut().zip(ys.iter()) { - *x += *y; - } -} - -// simd accelerated addition -fn simd_add_assign(xs: &mut Vec, ys: &Vec) { - assert_equal_len!(xs, ys); - - let size = xs.len() as isize; - let chunks = size / 4; - - // pointer to the start of the vector data - let p_x: *mut f32 = xs.as_mut_ptr(); - let p_y: *const f32 = ys.as_ptr(); - - // sum excess elements that don't fit in the simd vector - for i in (4 * chunks)..size { - // dereferencing a raw pointer requires an unsafe block - unsafe { - // offset by i elements - *p_x.offset(i) += *p_y.offset(i); - } - } - - // treat f32 vector as an simd f32x4 vector - let simd_p_x = p_x as *mut f32x4; - let simd_p_y = p_y as *const f32x4; - - // sum "simd vector" - for i in 0..chunks { - unsafe { - *simd_p_x.offset(i) += *simd_p_y.offset(i); - } - } -} - -mod bench { - extern crate test; - use self::test::Bencher; - use std::iter; - static BENCH_SIZE: usize = 10_000; - - macro_rules! bench { - ($name:ident, $func:ident) => { - #[bench] - fn $name(b: &mut Bencher) { - let mut x: Vec<_> = iter::repeat(1.0f32) - .take(BENCH_SIZE) - .collect(); - let y: Vec<_> = iter::repeat(1.0f32) - .take(BENCH_SIZE) - .collect(); - - b.iter(|| { - super::$func(&mut x, &y); - }) - } - } - } - - bench!(vanilla, add_assign); - bench!(simd, simd_add_assign); -} diff --git a/examples/unsafe/asm.rs b/examples/unsafe/asm.rs deleted file mode 100644 index bc34dd086c..0000000000 --- a/examples/unsafe/asm.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(asm)] - -fn add(a: i32, b: i32) -> i32 { - let sum: i32; - unsafe { - asm!("add $2, $1; mov $1, $0" : "=r"(sum) : "r"(a), "r"(b)); - } - sum -} diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.js b/node_modules/gitbook-plugin-rust-playpen/book/editor.js index 5afe0e5419..0d37c05cb3 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.js +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.js @@ -159,7 +159,7 @@ function escapeHTML(unsafe) { function runProgram(program, callback) { var req = new XMLHttpRequest(); var data = JSON.stringify({ - version: "nightly", + version: "stable", optimize: "0", code: program }); diff --git a/src/example.rs b/src/example.rs index cf4cf0f795..c5918ca0a4 100644 --- a/src/example.rs +++ b/src/example.rs @@ -37,7 +37,7 @@ impl Example { None => 1, Some(ref children) => 1 + children.iter() .map(|c| c.count()) - .sum::(), + .fold(0, |sum, i| sum + i), } } diff --git a/src/main.rs b/src/main.rs index 08d1892c2b..54f7ea1d0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,5 @@ -#![feature(iter_arith)] - #![deny(warnings)] #![allow(deprecated)] -#![feature(plugin)] extern crate regex; extern crate rustc_serialize; From f582264d394038b14d8e101638345d822cb90167 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 18:54:10 -0400 Subject: [PATCH 0330/1122] Thanks @mdinger, bringing back lots of closure stuff --- .../fn/closures/output_parameters/input.md | 26 +++++++++++++++++++ .../output_parameters/output_parameters.rs | 19 ++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 examples/fn/closures/output_parameters/input.md create mode 100644 examples/fn/closures/output_parameters/output_parameters.rs diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md new file mode 100644 index 0000000000..723bced478 --- /dev/null +++ b/examples/fn/closures/output_parameters/input.md @@ -0,0 +1,26 @@ +Closures as input parameters are possible so returning one should also be +possible. However, returning closure types are problematic because Rust +currently only supports returning concrete (non-generic) types. Anonymous +closure types are, by definition, unknown and so returning a closure is only +possible by making it concrete. This can be done via boxing. + +The valid types for returns are slightly different than before: + +* `Fn`: normal +* `FnMut`: normal + +Beyond this, the `move` keyword must be used which signals that all captures +occur by value. This is required because any captures by reference would be +dropped as soon as the function exited leaving invalid references in the +closure. + +{output_parameters.play} + +### See also: + +[Boxing][box], [`Fn`][fn], [`FnMut`][fnmut], and [Generics][generics]. + +[box]: /std/box.html +[fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html +[fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[generics]: /generics.html diff --git a/examples/fn/closures/output_parameters/output_parameters.rs b/examples/fn/closures/output_parameters/output_parameters.rs new file mode 100644 index 0000000000..0e09cd3c9a --- /dev/null +++ b/examples/fn/closures/output_parameters/output_parameters.rs @@ -0,0 +1,19 @@ +fn create_fn() -> Box { + let text = "Fn".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn create_fnmut() -> Box { + let text = "FnMut".to_owned(); + + Box::new(move || println!("This is a: {}", text)) +} + +fn main() { + let fn_plain = create_fn(); + let mut fn_mut = create_fnmut(); + + fn_plain(); + fn_mut(); +} From 827a3738ce89ed10085bf18551af625f82bdf39c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 19:03:18 -0400 Subject: [PATCH 0331/1122] update with missing files --- examples/structure.json | 7 ++----- examples/unsafe/input.md | 15 --------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/examples/structure.json b/examples/structure.json index c0e00640fa..d8eadab57b 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -106,7 +106,6 @@ { "id": "the_problem", "title": "The problem", "children": null }, { "id": "types", "title": "Associated types", "children": null }, { "id": "constrain", "title": "Constraining", "children": null }, - { "id": "consts", "title": "Associated consts", "children": null }, { "id": "testcase_add", "title": "Testcase: Add", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ @@ -173,13 +172,11 @@ { "id": "arg", "title": "Program arguments", "children": [ { "id": "matching", "title": "Argument parsing", "children": null } ] }, - { "id": "ffi", "title": "Foreign Function Interface", "children": null }, - { "id": "simd", "title": "SIMD", "children": null } + { "id": "ffi", "title": "Foreign Function Interface", "children": null } ] }, { "id": "meta", "title": "Meta", "children": [ { "id": "doc", "title": "Documentation", "children": null }, - { "id": "test", "title": "Testing", "children": null }, - { "id": "bench", "title": "Benchmarking", "children": null } + { "id": "test", "title": "Testing", "children": null } ] }, { "id": "unsafe", "title": "Unsafe operations", "children": null } ] diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index 9e9dc0a3e2..0678531b79 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -25,18 +25,3 @@ Allows simple conversion from one type to another, however both types must have the same size and alignment: {transmute.rs} - -### Inline Assembly -Inline assembly functions very similarly to the inline assembly of C, which -makes sense considering its implementation is not handled by rust, rather by -the LLVM. It allows for direct access to assembly manipulation, which can -massively increase speed, but it can also decrease portability and stability. -In most cases the compiler will optimize your rust code to better assembly than -you could write, so in most instances it is not worth it. The first parameter -of asm!() is the format of the assembly, the parameter following the colon is -the output variable, and the parameter(s) following that are the input -variables. - -**Note**: `#![feature(asm)]` is currently required to use inline assembly. - -{asm.rs} From 6f20a72ff3eb7c7149221e4edf3f870f753cefeb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 19:21:12 -0400 Subject: [PATCH 0332/1122] last @mdinger review --- examples/fn/closures/output_parameters/input.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index 723bced478..b8489ffe04 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -8,6 +8,9 @@ The valid types for returns are slightly different than before: * `Fn`: normal * `FnMut`: normal +* `FnOnce`: There is some unsual things at play here, so the [`FnBox`][fnbox] + type is currently needed, and is unstable. This is expected to change in + the future. Beyond this, the `move` keyword must be used which signals that all captures occur by value. This is required because any captures by reference would be @@ -23,4 +26,5 @@ closure. [box]: /std/box.html [fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html [fnmut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html +[fnbox]: http://doc.rust-lang.org/std/boxed/trait.FnBox.html [generics]: /generics.html From 00057f8f65269c27466a84f53c7c5987f7ca4e7d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 20:09:49 -0400 Subject: [PATCH 0333/1122] Travis :arrows_clockwise: We currently have a node Travis environment, and we install Rust into it. But that's not great. See, it'd be nice to be able to test against all three channels of Rust. So instead, let's make this a Rust env, and install Node into it. --- .travis.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3810728b97..b7a5a4b900 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,15 @@ -language: node_js +language: rust sudo: false +rust: + - stable + - beta + - nightly + install: - - curl -L https://static.rust-lang.org/rustup.sh | sh -s -- --yes --prefix=$PWD --disable-sudo --disable-ldconfig - - export PATH=$PATH:$PWD/bin - - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib + - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz + - tar xf node.tar.gz + - export PATH=$PATH:$pwd/node-v0.12.7-linux-x64/bin script: - rustc --version From 914036718d52d8f8acfd8005d01bd51eab08f067 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 17 Aug 2015 20:14:34 -0400 Subject: [PATCH 0334/1122] allow Travis to fail on nightly --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b7a5a4b900..caacc13e64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,10 @@ rust: - beta - nightly +matrix: + allow_failures: + - rust: nightly + install: - curl https://nodejs.org/dist/v0.12.7/node-v0.12.7-sunos-x64.tar.gz > node.tar.gz - tar xf node.tar.gz From e1f4f9b21fbedccd964d4e76f6f343aa928a9a4a Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 19 Aug 2015 15:25:11 -0400 Subject: [PATCH 0335/1122] Update text to spawn so it matches example --- examples/std_misc/threads/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/threads/input.md b/examples/std_misc/threads/input.md index a69d32e11b..6b304c720a 100644 --- a/examples/std_misc/threads/input.md +++ b/examples/std_misc/threads/input.md @@ -1,4 +1,4 @@ -Rust provides a mechanism for spawning native OS threads via the `scoped` +Rust provides a mechanism for spawning native OS threads via the `spawn` function, the argument of this function is a moving closure. {threads.play} From 50a53c13183fe54c51a43a17451b56af83585f8e Mon Sep 17 00:00:00 2001 From: Junhua Date: Mon, 14 Sep 2015 14:58:34 +0800 Subject: [PATCH 0336/1122] Update unit_test.rs Correct the error of calculating the distance between two points. --- examples/meta/test/unit_test.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/meta/test/unit_test.rs b/examples/meta/test/unit_test.rs index 9b470faf37..3a70c08e1f 100644 --- a/examples/meta/test/unit_test.rs +++ b/examples/meta/test/unit_test.rs @@ -10,8 +10,8 @@ mod test { // A helper function `distance_test` will need. fn distance(a: (f32, f32), b: (f32, f32)) -> f32 { ( - (b.0.powi(2) - a.0.powi(2)) + - (b.1.powi(2) - a.1.powi(2)) + (b.0 - a.0).powi(2) + + (b.1 - a.1).powi(2) ).sqrt() } From 3512f459f3cc83eb8eb89cf1f1f03334dcebc13f Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 30 Sep 2015 19:52:39 -0400 Subject: [PATCH 0337/1122] Revert "Use local highlighting file until ace-builds updates again" This reverts commit af64ffd0c6146ddcd9a1fdc5b9f156ed918716b8. --- node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak | 1 - setup-stage.sh | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak diff --git a/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak b/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak deleted file mode 100644 index 01562cc9ae..0000000000 --- a/node_modules/gitbook-plugin-rust-playpen/book/mode-rust.js.bak +++ /dev/null @@ -1 +0,0 @@ -ace.define("ace/mode/rust_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=/\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\})/.source,o=function(){this.$rules={start:[{token:"variable.other.source.rust",regex:"'[a-zA-Z_][a-zA-Z0-9_]*(?![\\\'])"},{token:"string.quoted.single.source.rust",regex:"'(?:[^'\\\\]|"+s+")'"},{stateName:"bracketedComment",onMatch:function(e,t,n){return n.unshift(this.next,e.length-1,t),"string.quoted.raw.source.rust"},regex:/r#*"/,next:[{onMatch:function(e,t,n){var r="string.quoted.raw.source.rust";return e.length>=n[1]?(e.length>n[1]&&(r="invalid"),n.shift(),n.shift(),this.next=n.shift()):this.next="",r},regex:/"#*/,next:"start"},{defaultToken:"string.quoted.raw.source.rust"}]},{token:"string.quoted.double.source.rust",regex:'"',push:[{token:"string.quoted.double.source.rust",regex:'"',next:"pop"},{token:"constant.character.escape.source.rust",regex:s},{defaultToken:"string.quoted.double.source.rust"}]},{token:["keyword.source.rust","text","entity.name.function.source.rust"],regex:"\\b(fn)(\\s+)([a-zA-Z_][a-zA-Z0-9_]*)"},{token:"support.constant",regex:"\\b[a-zA-Z_][\\w\\d]*::"},{token:"keyword.source.rust",regex:"\\b(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\\b"},{token:"storage.type.source.rust",regex:"\\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b"},{token:"variable.language.source.rust",regex:"\\bself\\b"},{token:"keyword.operator",regex:/\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/},{token:"punctuation.operator",regex:/[?:,;.]/},{token:"paren.lparen",regex:/[\[({]/},{token:"paren.rparen",regex:/[\])}]/},{token:"constant.language.source.rust",regex:"\\b(?:true|false|Some|None|Ok|Err)\\b"},{token:"support.constant.source.rust",regex:"\\b(?:EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\\b"},{token:"meta.preprocessor.source.rust",regex:"\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b"},{token:"constant.numeric.integer.source.rust",regex:"\\b(?:[0-9][0-9_]*|[0-9][0-9_]*(?:u|us|u8|u16|u32|u64)|[0-9][0-9_]*(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.hex.source.rust",regex:"\\b(?:0x[a-fA-F0-9_]+|0x[a-fA-F0-9_]+(?:u|us|u8|u16|u32|u64)|0x[a-fA-F0-9_]+(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.binary.source.rust",regex:"\\b(?:0b[01_]+|0b[01_]+(?:u|us|u8|u16|u32|u64)|0b[01_]+(?:i|is|i8|i16|i32|i64))\\b"},{token:"constant.numeric.float.source.rust",regex:"[0-9][0-9_]*(?:f32|f64|f)|[0-9][0-9_]*[eE][+-]=[0-9_]+|[0-9][0-9_]*[eE][+-]=[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+|[0-9][0-9_]*\\.[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+(?:f32|f64|f)"},{token:"comment.line.documentation.source.rust",regex:"//!.*$",push_:[{token:"comment.line.documentation.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.documentation.source.rust"}]},{token:"comment.line.double-dash.source.rust",regex:"//.*$",push_:[{token:"comment.line.double-dash.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.source.rust"}]},{token:"comment.start.block.source.rust",regex:"/\\*",stateName:"comment",push:[{token:"comment.start.block.source.rust",regex:"/\\*",push:"comment"},{token:"comment.end.block.source.rust",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.source.rust"}]}]},this.normalizeRules()};o.metaData={fileTypes:["rs","rc"],foldingStartMarker:"^.*\\bfn\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$",foldingStopMarker:"^\\s*\\}",name:"Rust",scopeName:"source.rust"},r.inherits(o,i),t.RustHighlightRules=o}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/rust",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/rust_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./rust_highlight_rules").RustHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/rust"}.call(u.prototype),t.Mode=u}) diff --git a/setup-stage.sh b/setup-stage.sh index f45626264f..eca4b5fed2 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -6,8 +6,7 @@ ace_playpen_local='node_modules/gitbook-plugin-rust-playpen' mkdir -p bin mkdir -p stage/node_modules svn checkout ${ace_repository} ${ace_playpen_local}'/book/ace' -# cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' -cp ${ace_playpen_local}'/book/mode-rust.js.bak' ${ace_playpen_local}'/book/mode-rust.js' +cp ${ace_playpen_local}'/book/ace/mode-rust.js' ${ace_playpen_local}'/book/mode-rust.js' ln -sf ../book.json stage ln -sf ../examples/README.md stage From 505324d11c595364f1073db782b6be27c6c1f777 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 30 Sep 2015 19:57:13 -0400 Subject: [PATCH 0338/1122] Update cargo lock --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a9e8a4635..113584031b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,28 +3,28 @@ name = "update" version = "0.0.1" dependencies = [ "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -32,18 +32,18 @@ name = "regex" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" From 7a0b7f0494ec8bf42147be5f8591914a1f9cf8e6 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 30 Sep 2015 21:02:37 -0400 Subject: [PATCH 0339/1122] Using min fixes playpen. Not sure why --- setup-stage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup-stage.sh b/setup-stage.sh index eca4b5fed2..8d02ed3ff9 100755 --- a/setup-stage.sh +++ b/setup-stage.sh @@ -1,6 +1,6 @@ #!/bin/bash -ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min-noconflict' +ace_repository='https://github.com/ajaxorg/ace-builds/trunk/src-min' ace_playpen_local='node_modules/gitbook-plugin-rust-playpen' mkdir -p bin From 8ffe58c43bcb83f7dd83c457dcc53df9d3bf83ed Mon Sep 17 00:00:00 2001 From: vthib Date: Thu, 8 Oct 2015 10:44:52 +0200 Subject: [PATCH 0340/1122] print_display/testcase_list: fix issue with zero-length vector The implementation given to implement fmt::Display with a Vec works fine, as long as the vector is not empty. If it is, vec[len-1] is accessed, leading to a run-time panic. The issue is that a fmt::Result value must be returned in the end, and as the example did not used any brackets to surround the printed values, empty vector would have meant nothing to print. A "Ok(())" could be returned, but this isn't elegant or best for an example of pretty Rust code. '[' and ']' are therefore added around the printed values, and the code is reworked to print a comma before every element that is not the first one. --- .../print_display/testcase_list/testcase_list.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/hello/print/print_display/testcase_list/testcase_list.rs b/examples/hello/print/print_display/testcase_list/testcase_list.rs index 79d2b707cf..0f7128c72d 100644 --- a/examples/hello/print/print_display/testcase_list/testcase_list.rs +++ b/examples/hello/print/print_display/testcase_list/testcase_list.rs @@ -8,18 +8,20 @@ impl fmt::Display for List { // Dereference `self` and create a reference to `vec` // via destructuring. let List(ref vec) = *self; - let len = vec.len(); // Save the vector length in `len`. + + try!(write!(f, "[")); // Iterate over `vec` in `v` while enumerating the iteration // count in `count`. for (count, v) in vec.iter().enumerate() { - // For every element except the last, format `write!` - // with a comma. Use `try!` to return on errors. - if count < len - 1 { try!(write!(f, "{}, ", v)) } + // For every element except the first, add a comma + // before calling `write!`. Use `try!` to return on errors. + if count != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{}", v)); } - // `write!` the last value without special formatting. - write!(f, "{}", vec[len-1]) + // Close the opened bracket and return a fmt::Result value + write!(f, "]") } } From 07c0385f33b41a121ca6a368db7828295913eb80 Mon Sep 17 00:00:00 2001 From: ia0 Date: Tue, 13 Oct 2015 22:44:53 +0200 Subject: [PATCH 0341/1122] std_misc/arg/matching: fix match_args.rs to match input.md --- examples/std_misc/arg/matching/match_args.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/std_misc/arg/matching/match_args.rs b/examples/std_misc/arg/matching/match_args.rs index b77136ad3e..bb8e7cc666 100644 --- a/examples/std_misc/arg/matching/match_args.rs +++ b/examples/std_misc/arg/matching/match_args.rs @@ -26,10 +26,9 @@ fn main() { }, // one argument passed 2 => { - if &42 == &args[1].parse().unwrap() { - println!("This is the answer!"); - } else { - println!("This is not the answer."); + match args[1].parse() { + Ok(42) => println!("This is the answer!"), + _ => println!("This is not the answer."), } }, // one command and one argument passed From 5e719daa632892e9b28a2bf6b8eab7d766d99290 Mon Sep 17 00:00:00 2001 From: ia0 Date: Tue, 13 Oct 2015 23:32:40 +0200 Subject: [PATCH 0342/1122] unsafe: fix broken link --- examples/unsafe/input.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/unsafe/input.md b/examples/unsafe/input.md index 0678531b79..a1f0807ab1 100644 --- a/examples/unsafe/input.md +++ b/examples/unsafe/input.md @@ -1,7 +1,6 @@ As an introduction to this section, to borrow from [the official docs]( -http://doc.rust-lang.org/master/guide-unsafe.html), "one should try to -minimize the amount of unsafe code in a code base." With that in mind, let's -get started! +http://doc.rust-lang.org/book/unsafe.html), "one should try to minimize the +amount of unsafe code in a code base." With that in mind, let's get started! Unsafe blocks in Rust are used to bypass protections put in place by the compiler; specifically, there are four primary things that unsafe blocks are used for: From 077b8a1c5b00ae952a968d6189f90322b4d5e24c Mon Sep 17 00:00:00 2001 From: mdinger Date: Tue, 27 Oct 2015 17:11:25 -0400 Subject: [PATCH 0343/1122] Update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 113584031b..e0739c3564 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -32,7 +32,7 @@ name = "regex" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] From fd5eadfd3d1fe06583c37e6cc563e6e9414b8e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Matthias=20Sch=C3=A4fer?= Date: Thu, 5 Nov 2015 09:55:59 +0100 Subject: [PATCH 0344/1122] fn/methods: fix orthography --- examples/fn/methods/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/methods/input.md b/examples/fn/methods/input.md index 6e725cfa37..1bedf82be7 100644 --- a/examples/fn/methods/input.md +++ b/examples/fn/methods/input.md @@ -1,5 +1,5 @@ Methods are functions attached to objects. These methods have access to the data of the object and its other methods via the `self` keyword. Methods are -defined under a `impl` block. +defined under an `impl` block. {methods.play} From 9ea7285b8f384399449855cd058df665ce76e298 Mon Sep 17 00:00:00 2001 From: Andrew Reece Date: Tue, 10 Nov 2015 10:46:50 +0000 Subject: [PATCH 0345/1122] Fix typo "exacty" to "exactly" --- .../match/destructuring/destructure_pointers/pointers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs b/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs index 9bef33c1da..9e59fc40d6 100644 --- a/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs +++ b/examples/flow_control/match/destructuring/destructure_pointers/pointers.rs @@ -23,7 +23,7 @@ fn main() { // a reference because the right side is not one. let _not_a_reference = 3; - // Rust provides `ref` for exacty this purpose. It modifies the + // Rust provides `ref` for exactly this purpose. It modifies the // assignment so that a reference is created for the element; this // reference is assigned. let ref _is_a_reference = 3; From bc51889d8db65f6b70d6bbe2369dc1a3c309bc54 Mon Sep 17 00:00:00 2001 From: dopin Date: Thu, 12 Nov 2015 19:03:57 +0900 Subject: [PATCH 0346/1122] Add alignment and fill examples in 1.2 Formatted print --- examples/hello/print/print.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs index 9d978279da..c5cafc49ea 100644 --- a/examples/hello/print/print.rs +++ b/examples/hello/print/print.rs @@ -19,6 +19,17 @@ fn main() { // Special formatting can be specified after a `:`. println!("{} of {:b} people know binary, the other half don't", 1, 2); + // You can right-align text with a specified width. This will output + // " 1". 5 white spaces and a "1". + println!("{number:>width$}", + number=1, + width=6); + + // You can pad numbers with extra zeroes. This will output "000001". + println!("{number:>0width$}", + number=1, + width=6); + // It will even check to make sure the correct number of arguments are // used. println!("My name is {0}, {1} {0}", "Bond"); From ecd66bd1e6fe5d44f7bce68e256adcc08b23ef04 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 12 Nov 2015 17:23:13 -0500 Subject: [PATCH 0347/1122] Max line length is 99 not 79 --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3c98d95983..f2fb098710 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,7 +64,7 @@ See the [README][readme] for details about how the static site is generated. ## Markdown (.md) -* Lines should contain a maximum of 79 characters. +* Lines should contain a maximum of 99 characters. * Use reference style hyperlinks, for example: Instead of: @@ -80,7 +80,7 @@ Use: ## Rust code (.rs) -* Lines should contain a maximum of 79 characters. +* Lines should contain a maximum of 99 characters. * In comments, types, methods, macros and variables should be wrapped in backticks, e.g. ``` `println!` ``` From 2c4576df95017029aa4d86a1f1e930e2e6e725b6 Mon Sep 17 00:00:00 2001 From: dopin Date: Fri, 13 Nov 2015 07:25:31 +0900 Subject: [PATCH 0348/1122] Remove extra break lines in print.rs --- examples/hello/print/print.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs index c5cafc49ea..d8f3906357 100644 --- a/examples/hello/print/print.rs +++ b/examples/hello/print/print.rs @@ -21,14 +21,10 @@ fn main() { // You can right-align text with a specified width. This will output // " 1". 5 white spaces and a "1". - println!("{number:>width$}", - number=1, - width=6); + println!("{number:>width$}", number=1, width=6); // You can pad numbers with extra zeroes. This will output "000001". - println!("{number:>0width$}", - number=1, - width=6); + println!("{number:>0width$}", number=1, width=6); // It will even check to make sure the correct number of arguments are // used. From 9a459c011e286cddeeac71fd193e995be21bea44 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Sat, 14 Nov 2015 21:37:36 +1100 Subject: [PATCH 0349/1122] Add an exlicit activity. --- examples/hello/input.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/hello/input.md b/examples/hello/input.md index 46dc674b13..c40b7208c0 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -5,6 +5,14 @@ This is the source code of the traditional Hello World program. `println!` is a [*macro*][macros] that prints text to the console. +Activity: Click 'Run' above to see the expected output. Next, add a new +line with a second `println!` macro so that the output +shows: +``` +Hello World! +I'm a Rustacian! +``` + A binary can be generated using the Rust compiler: `rustc`. ``` From a7dca1a661601e729528c3c278e2bcf263574910 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Sun, 15 Nov 2015 11:07:50 +0000 Subject: [PATCH 0350/1122] Updated formatting for activity (add bold) --- examples/hello/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/input.md b/examples/hello/input.md index c40b7208c0..73aceab892 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -5,7 +5,7 @@ This is the source code of the traditional Hello World program. `println!` is a [*macro*][macros] that prints text to the console. -Activity: Click 'Run' above to see the expected output. Next, add a new +**Activity**: Click 'Run' above to see the expected output. Next, add a new line with a second `println!` macro so that the output shows: ``` From 1aa736185a80bedbeb3e7e63e9e38ab1a10afeb7 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Sun, 15 Nov 2015 11:08:12 +0000 Subject: [PATCH 0351/1122] Add print activities. --- examples/hello/print/input.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index cb26fdddec..18cad3ccc5 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -10,6 +10,14 @@ be checked at compile time. {print.play} +**Activities**: + * Fix the two isses in the above code (see FIXME) so that it runs +without error. + * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two + divided by seven to generate the estimate for Pi. (Hint: you may need to + check the [`std::fmt`][fmt] documentation for setting the number of + decimals to display) + [`std::fmt`][fmt] contains many [`traits`][traits] which govern the display of text. The base form of two important ones are listed below: From 3eef4b0a5b8b944f394f8747296cf1dc02716ec7 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Sun, 15 Nov 2015 11:17:18 +0000 Subject: [PATCH 0352/1122] Fix text alignment. --- examples/hello/print/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index 18cad3ccc5..e7a9ee8ec4 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -11,8 +11,8 @@ be checked at compile time. {print.play} **Activities**: - * Fix the two isses in the above code (see FIXME) so that it runs -without error. + * Fix the two isses in the above code (see FIXME) so that it runs without + error. * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two divided by seven to generate the estimate for Pi. (Hint: you may need to check the [`std::fmt`][fmt] documentation for setting the number of From 2e39d51115dcbb285097eff75fa691ce2c434a36 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Mon, 16 Nov 2015 10:49:24 +0000 Subject: [PATCH 0353/1122] Try heading at the end for activities. --- examples/hello/input.md | 18 ++++++++++-------- examples/hello/print/input.md | 17 +++++++++-------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/hello/input.md b/examples/hello/input.md index 73aceab892..d45ea7d222 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -5,14 +5,6 @@ This is the source code of the traditional Hello World program. `println!` is a [*macro*][macros] that prints text to the console. -**Activity**: Click 'Run' above to see the expected output. Next, add a new -line with a second `println!` macro so that the output -shows: -``` -Hello World! -I'm a Rustacian! -``` - A binary can be generated using the Rust compiler: `rustc`. ``` @@ -26,4 +18,14 @@ $ ./hello Hello World! ``` +### Activity + +Click 'Run' above to see the expected output. Next, add a new +line with a second `println!` macro so that the output +shows: +``` +Hello World! +I'm a Rustacian! +``` + [macros]: ./macros.html diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index e7a9ee8ec4..e0afde8075 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -10,14 +10,6 @@ be checked at compile time. {print.play} -**Activities**: - * Fix the two isses in the above code (see FIXME) so that it runs without - error. - * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two - divided by seven to generate the estimate for Pi. (Hint: you may need to - check the [`std::fmt`][fmt] documentation for setting the number of - decimals to display) - [`std::fmt`][fmt] contains many [`traits`][traits] which govern the display of text. The base form of two important ones are listed below: @@ -28,6 +20,15 @@ friendly fashion. Here, `fmt::Display` was used because the std library provides implementations for these types. To print text for custom types, more steps are required. +### Activities + + * Fix the two isses in the above code (see FIXME) so that it runs without + error. + * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two + divided by seven to generate the estimate for Pi. (Hint: you may need to + check the [`std::fmt`][fmt] documentation for setting the number of + decimals to display) + ### See also: [`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], From 7f4df5a6fc8ca33f46e96bbc9ee47d389d36abb7 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Mon, 16 Nov 2015 20:02:43 +0000 Subject: [PATCH 0354/1122] Remove colon from See also --- examples/hello/print/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index e0afde8075..db01c6fc56 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -29,7 +29,7 @@ for these types. To print text for custom types, more steps are required. check the [`std::fmt`][fmt] documentation for setting the number of decimals to display) -### See also: +### See also [`std::fmt`][fmt], [`macros`][macros], [`struct`][structs], and [`traits`][traits] From 232b611a166aa65c7d18aa5756f37d30f509b81f Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Tue, 17 Nov 2015 11:56:39 +0000 Subject: [PATCH 0355/1122] Add activity for print_display. --- examples/hello/print/print_debug/input.md | 2 +- examples/hello/print/print_display/input.md | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/print_debug/input.md b/examples/hello/print/print_debug/input.md index b48db8686e..876dfafc6f 100644 --- a/examples/hello/print/print_debug/input.md +++ b/examples/hello/print/print_debug/input.md @@ -25,7 +25,7 @@ All std library types automatically are printable with `{:?}` too: So `fmt::Debug` definitely makes this printable but sacrifices some elegance. Manually implementing `fmt::Display` will fix that. -### See also: +### See also [attributes][attributes], [`derive`][derive], [`std::fmt`][fmt], and [`struct`][structs] diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 26247ed6bc..6ecebf7138 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -48,7 +48,16 @@ therefore cannot be used. `std::fmt` has many such [`traits`][traits] and each requires it's own implementation. This is detailed further in [`std::fmt`][fmt]. -### See also: +### Activity + +Using the `Point2` struct as an example, add a Complex struct to the example +above. When printed in the same way, the output should be: +``` +Display: 3.3 + 7.2i +Debug: Complex { real: 3.3, imag: 7.2 } +``` + +### See also [`derive`][derive], [`std::fmt`][fmt], [macros], [`struct`][structs], [`trait`][traits], and [use][use] From 446d22e43ef6bf209c7b6d61ea5dc63e7968eed6 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Wed, 18 Nov 2015 12:02:34 +0000 Subject: [PATCH 0356/1122] Add activity for the format example. --- examples/hello/print/fmt/input.md | 33 ++++++++++++------- examples/hello/print/fmt/show.rs | 17 +++++++++- examples/hello/print/print_display/input.md | 5 +-- .../print_display/testcase_list/input.md | 2 +- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/examples/hello/print/fmt/input.md b/examples/hello/print/fmt/input.md index 95c38aa70a..f4bb6bb57d 100644 --- a/examples/hello/print/fmt/input.md +++ b/examples/hello/print/fmt/input.md @@ -14,16 +14,27 @@ handles cases where the argument type is left unspecified: `{}` for instance. {show.play} -Here's the full list of formatting traits and their respective argument types: - -* *unspecified* -> `Display` -* `?` -> `Debug` -* `o` -> `Octal` -* `x` -> `LowerHex` -* `X` -> `UpperHex` -* `p` -> `Pointer` -* `b` -> `Binary` -* `e` -> `LowerExp` -* `E` -> `UpperExp` +You can view a [full list of formatting traits][fmt_traits] and their argument +types in the [`std::fmt`][fmt] documentation. +### Activity +Add an implementation of the `fmt::Display` trait for the `Color` struct above +so that the output displays as: + +``` +RGB (128, 255, 90) 0x80FF5A +RGB (0, 3, 254) 0x0003FE +RGB (0, 0, 0) 0x000000 +``` +Two hints in case you get stuck: + * You [may need to list each color more than once][argument_types], + * You can [pad with zeros to a width of 2][fmt_width] with `:02`. + +### See also +[`std::fmt`][fmt] + +[argument_types]: http://doc.rust-lang.org/std/fmt/#argument-types [deadbeef]: https://en.wikipedia.org/wiki/Deadbeef#Magic_debug_values +[fmt]: http://doc.rust-lang.org/std/fmt/ +[fmt_traits]: http://doc.rust-lang.org/std/fmt/#formatting-traits +[fmt_width]: http://doc.rust-lang.org/std/fmt/#width diff --git a/examples/hello/print/fmt/show.rs b/examples/hello/print/fmt/show.rs index 4765402bf6..d616b1c481 100644 --- a/examples/hello/print/fmt/show.rs +++ b/examples/hello/print/fmt/show.rs @@ -21,6 +21,13 @@ impl Display for City { } } +#[derive(Debug)] +struct Color { + red: u8, + green: u8, + blue: u8, +} + fn main() { for city in [ City { name: "Dublin", lat: 53.347778, lon: -6.259722 }, @@ -29,5 +36,13 @@ fn main() { ].iter() { println!("{}", *city); } + for color in [ + Color { red: 128, green: 255, blue: 90 }, + Color { red: 0, green: 3, blue: 254 }, + Color { red: 0, green: 0, blue: 0 }, + ].iter() { + // Switch this to use {} once you've added an implementation + // for fmt::Display + println!("{:?}", *color) + } } - diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index 6ecebf7138..a3e86e3e1c 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -50,8 +50,9 @@ each requires it's own implementation. This is detailed further in ### Activity -Using the `Point2` struct as an example, add a Complex struct to the example -above. When printed in the same way, the output should be: +After checking the output of the above example, use the `Point2` struct as +guide to add a Complex struct to the example. When printed in the same +way, the output should be: ``` Display: 3.3 + 7.2i Debug: Complex { real: 3.3, imag: 7.2 } diff --git a/examples/hello/print/print_display/testcase_list/input.md b/examples/hello/print/print_display/testcase_list/input.md index 784db00599..61ad10532b 100644 --- a/examples/hello/print/print_display/testcase_list/input.md +++ b/examples/hello/print/print_display/testcase_list/input.md @@ -16,7 +16,7 @@ straightforward: {testcase_list.play} -### See also: +### See also [`for`][for], [`ref`][ref], [`Result`][result], [`struct`][struct], [`try!`][try], and [`vec!`][vec] From f4eb460a8626bc537b4a8b8230d29a7a735ae706 Mon Sep 17 00:00:00 2001 From: jmr0 Date: Wed, 18 Nov 2015 19:01:13 -0500 Subject: [PATCH 0357/1122] custom_types/constants: fix typo --- examples/custom_types/constants/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_types/constants/input.md b/examples/custom_types/constants/input.md index 1dc71172c7..e415e4fa5b 100644 --- a/examples/custom_types/constants/input.md +++ b/examples/custom_types/constants/input.md @@ -1,7 +1,7 @@ Rust has two different types of constants which can be declared in any scope including global. Both require explicit type annotation: -* `const`: An unchangable value (the common case). +* `const`: An unchangeable value (the common case). * `static`: A possibly `mut`able variable with [`'static`][static] lifetime. One special case is the `"string"` literal. It can be assigned directly to a From 4e8d751d754eb86d823c50f54112cc2577256e9a Mon Sep 17 00:00:00 2001 From: jmr0 Date: Wed, 18 Nov 2015 22:46:37 -0500 Subject: [PATCH 0358/1122] fn/closures/closure_analysis/iter_any: small grammar fix --- examples/fn/closures/closure_analysis/iter_any/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/closure_analysis/iter_any/input.md b/examples/fn/closures/closure_analysis/iter_any/input.md index 59c3516f9e..5784888d68 100644 --- a/examples/fn/closures/closure_analysis/iter_any/input.md +++ b/examples/fn/closures/closure_analysis/iter_any/input.md @@ -1,5 +1,5 @@ `Iterator::any` is a function which when passed an iterator, will return -`true` if any element satisfies the predicate. Otherwise `false`. It's +`true` if any element satisfies the predicate. Otherwise `false`. Its signature: ```rust From 92e4b3b03d357a012b933cf33d2e5476eb7f25d6 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Mon, 23 Nov 2015 10:28:45 +0000 Subject: [PATCH 0359/1122] Add an activity for the tuples example. --- examples/hello/print/fmt/input.md | 2 +- examples/primitives/tuples/input.md | 29 ++++++++++++++++++++++++++++ examples/primitives/tuples/tuples.rs | 10 +++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/examples/hello/print/fmt/input.md b/examples/hello/print/fmt/input.md index f4bb6bb57d..a132ef1682 100644 --- a/examples/hello/print/fmt/input.md +++ b/examples/hello/print/fmt/input.md @@ -26,7 +26,7 @@ RGB (128, 255, 90) 0x80FF5A RGB (0, 3, 254) 0x0003FE RGB (0, 0, 0) 0x000000 ``` -Two hints in case you get stuck: +Two hints if you get stuck: * You [may need to list each color more than once][argument_types], * You can [pad with zeros to a width of 2][fmt_width] with `:02`. diff --git a/examples/primitives/tuples/input.md b/examples/primitives/tuples/input.md index a541373979..836e449cdf 100644 --- a/examples/primitives/tuples/input.md +++ b/examples/primitives/tuples/input.md @@ -4,3 +4,32 @@ using parentheses `()`, and each tuple itself is a value with type signature use tuples to return multiple values, as tuples can hold any number of values. {tuples.play} + +### Activity + + 1. *Recap*: Add the `fmt::Display` trait to the Matrix `struct` in the above example, + so that if you switch from printing the debug format `{:?}` to the display + format `{}`, you see the following output: +``` +( 1.1 1.2 ) +( 2.1 2.2 ) +``` + You may want to refer back to the example for [print display](print_display). + 2. Add a `transpose` function using the `reverse` function as a template, which + accepts a matrix as an argument, and returns a matrix in which two elements + have been swapped. For example: +``` +print!("Matrix:\n{}", matrix) +print!("Transpose:\n{}", transpose(matrix)) +``` +results in the output: +``` +Matrix: +( 1.1 1.2 ) +( 2.1 2.2 ) +Transpose: +( 1.1 2.1 ) +( 1.2 2.2 ) +``` + +[print_display]: /hello/print/print_display.html diff --git a/examples/primitives/tuples/tuples.rs b/examples/primitives/tuples/tuples.rs index d6f8d8742f..2c846470cc 100644 --- a/examples/primitives/tuples/tuples.rs +++ b/examples/primitives/tuples/tuples.rs @@ -6,6 +6,10 @@ fn reverse(pair: (i32, bool)) -> (bool, i32) { (boolean, integer) } +// The following struct is for the activity. +#[derive(Debug)] +struct Matrix(f32, f32, f32, f32); + fn main() { // A tuple with a bunch of different types let long_tuple = (1u8, 2u16, 3u32, 4u64, @@ -32,10 +36,14 @@ fn main() { // from a literal surrounded by parentheses println!("one element tuple: {:?}", (5u32,)); println!("just an integer: {:?}", (5u32)); - + //tuples can be destructured to create bindings let tuple = (1, "hello", 4.5, true); let (a, b, c, d) = tuple; println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d); + + let matrix = Matrix(1.1, 1.2, 2.1, 2.2); + println!("{:?}", matrix) + } From c3430c6e2e267cf8b84c03cd668ca6f99881fba5 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Mon, 23 Nov 2015 21:38:49 +0000 Subject: [PATCH 0360/1122] Use the correct println! macro. --- examples/primitives/tuples/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/primitives/tuples/input.md b/examples/primitives/tuples/input.md index 836e449cdf..fa538aa655 100644 --- a/examples/primitives/tuples/input.md +++ b/examples/primitives/tuples/input.md @@ -19,8 +19,8 @@ use tuples to return multiple values, as tuples can hold any number of values. accepts a matrix as an argument, and returns a matrix in which two elements have been swapped. For example: ``` -print!("Matrix:\n{}", matrix) -print!("Transpose:\n{}", transpose(matrix)) +println!("Matrix:\n{}", matrix) +println!("Transpose:\n{}", transpose(matrix)) ``` results in the output: ``` From 8aa5a880dc6b655056a3d787ade4d3e93fb16475 Mon Sep 17 00:00:00 2001 From: jmr0 Date: Fri, 27 Nov 2015 15:49:47 -0500 Subject: [PATCH 0361/1122] scope/lifetime/explicit: fixing comma position --- examples/scope/lifetime/explicit/explicit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index 488bf9a566..a5fc09cb03 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -27,7 +27,7 @@ fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { } // There are no references to force `'a` to be larger than the -// function yet, `'a` remains larger than the function. +// function, yet `'a` remains larger than the function. fn failed_borrow<'a>() { let _x = 12; From da19b67b2d2772251804681a102984c4af083838 Mon Sep 17 00:00:00 2001 From: Phoebe Queen Date: Sun, 29 Nov 2015 11:45:21 +0000 Subject: [PATCH 0362/1122] Fixed broken link --- examples/primitives/tuples/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/primitives/tuples/input.md b/examples/primitives/tuples/input.md index fa538aa655..1a4f0c8bf5 100644 --- a/examples/primitives/tuples/input.md +++ b/examples/primitives/tuples/input.md @@ -14,7 +14,7 @@ use tuples to return multiple values, as tuples can hold any number of values. ( 1.1 1.2 ) ( 2.1 2.2 ) ``` - You may want to refer back to the example for [print display](print_display). + You may want to refer back to the example for [print display][print_display]. 2. Add a `transpose` function using the `reverse` function as a template, which accepts a matrix as an argument, and returns a matrix in which two elements have been swapped. For example: From cb689be931092a8bf334a00dfd32541d7cd52ce0 Mon Sep 17 00:00:00 2001 From: Ian Whitney Date: Sun, 29 Nov 2015 15:50:45 -0600 Subject: [PATCH 0363/1122] contributing: fix typo It's is the correct word here. Considering that the typo was in the line about submitting PRs for typos, I find this a fun commit! --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2fb098710..11415641b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ not clear". The example id is the relative path in the URL without the html extension, e.g. URL: `http://rustbyexample.com/variables/scope.html` -> id: `variables/scope` -If its something simple like a typo, you can send a PR directly. +If it's something simple like a typo, you can send a PR directly. # Sending a PR for a small fix From 476fcc873d44a09ee232de277cbb6562f61cf5fc Mon Sep 17 00:00:00 2001 From: Ian Whitney Date: Sun, 29 Nov 2015 15:51:51 -0600 Subject: [PATCH 0364/1122] closures/anonymity: fix typo Replacing incorrect "it's" with "its" --- examples/fn/closures/anonymity/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index 7dc8410d34..c1a9f0b2c6 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -19,7 +19,7 @@ is stored until calling. Since this new type is of unknown type, any usage in a function will require generics. However, an unbounded type parameter (``) would still be ambiguous and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or -`FnOnce` (which it implements) is sufficient to specify it's type. +`FnOnce` (which it implements) is sufficient to specify its type. {anonymity.play} From 50fe8039578036ec46553bf359b4e73fcb839e1a Mon Sep 17 00:00:00 2001 From: Ian Whitney Date: Sun, 29 Nov 2015 15:52:48 -0600 Subject: [PATCH 0365/1122] print/print_display: fix typo Replace incorrect "it's" with "its" --- examples/hello/print/print_display/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_display/input.md b/examples/hello/print/print_display/input.md index a3e86e3e1c..3f8246ad4a 100644 --- a/examples/hello/print/print_display/input.md +++ b/examples/hello/print/print_display/input.md @@ -45,7 +45,7 @@ This is not a problem though because for any new *container* type which is So, `fmt::Display` has been implemented but `fmt::Binary` has not, and therefore cannot be used. `std::fmt` has many such [`traits`][traits] and -each requires it's own implementation. This is detailed further in +each requires its own implementation. This is detailed further in [`std::fmt`][fmt]. ### Activity From 950786e2acf331d5e5645ebec558b5633a6a2dc4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Mon, 30 Nov 2015 20:19:51 -0500 Subject: [PATCH 0366/1122] Add new error handling section --- examples/error/error.rs | 12 +++ examples/error/error_vs_absence/input.md | 23 ++++++ examples/error/error_vs_absence/result.rs | 14 ++++ examples/error/input.md | 16 ++++ examples/error/limits_of_strings/input.md | 27 +++++++ examples/error/limits_of_strings/rethink.rs | 59 +++++++++++++++ examples/error/map/input.md | 22 ++++++ examples/error/map/map.rs | 60 +++++++++++++++ .../error/more_combinators/combinators.rs | 53 +++++++++++++ examples/error/more_combinators/input.md | 30 ++++++++ .../combinator_combinations/input.md | 15 ++++ .../combinator_combinations/result_try.rs | 49 ++++++++++++ .../option_with_result/enter_try/input.md | 26 +++++++ .../error/option_with_result/enter_try/try.rs | 47 ++++++++++++ examples/error/option_with_result/input.md | 16 ++++ .../error/option_with_result/option_result.rs | 20 +++++ .../result_string_errors/input.md | 17 +++++ .../result_string_errors/result_string.rs | 32 ++++++++ examples/error/reenabling_box/input.md | 41 ++++++++++ examples/error/reenabling_box/rethink.rs | 75 +++++++++++++++++++ examples/error/reenter_try/input.md | 42 +++++++++++ examples/error/reenter_try/rethink.rs | 56 ++++++++++++++ examples/error/result_alias/alias.rs | 23 ++++++ examples/error/result_alias/input.md | 16 ++++ examples/error/result_map/input.md | 21 ++++++ examples/error/result_map/result.rs | 34 +++++++++ examples/error/unwrap/input.md | 23 ++++++ examples/error/unwrap/unwrap.rs | 36 +++++++++ examples/structure.json | 16 ++++ 29 files changed, 921 insertions(+) create mode 100644 examples/error/error.rs create mode 100644 examples/error/error_vs_absence/input.md create mode 100644 examples/error/error_vs_absence/result.rs create mode 100644 examples/error/input.md create mode 100644 examples/error/limits_of_strings/input.md create mode 100644 examples/error/limits_of_strings/rethink.rs create mode 100644 examples/error/map/input.md create mode 100644 examples/error/map/map.rs create mode 100644 examples/error/more_combinators/combinators.rs create mode 100644 examples/error/more_combinators/input.md create mode 100644 examples/error/option_with_result/combinator_combinations/input.md create mode 100644 examples/error/option_with_result/combinator_combinations/result_try.rs create mode 100644 examples/error/option_with_result/enter_try/input.md create mode 100644 examples/error/option_with_result/enter_try/try.rs create mode 100644 examples/error/option_with_result/input.md create mode 100644 examples/error/option_with_result/option_result.rs create mode 100644 examples/error/option_with_result/result_string_errors/input.md create mode 100644 examples/error/option_with_result/result_string_errors/result_string.rs create mode 100644 examples/error/reenabling_box/input.md create mode 100644 examples/error/reenabling_box/rethink.rs create mode 100644 examples/error/reenter_try/input.md create mode 100644 examples/error/reenter_try/rethink.rs create mode 100644 examples/error/result_alias/alias.rs create mode 100644 examples/error/result_alias/input.md create mode 100644 examples/error/result_map/input.md create mode 100644 examples/error/result_map/result.rs create mode 100644 examples/error/unwrap/input.md create mode 100644 examples/error/unwrap/unwrap.rs diff --git a/examples/error/error.rs b/examples/error/error.rs new file mode 100644 index 0000000000..8d3d21193b --- /dev/null +++ b/examples/error/error.rs @@ -0,0 +1,12 @@ +fn give_princess(gift: &str) { + // Princesses hate snakes so definitely stop the computation while + // she shouts her dislike. + if gift == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", gift); +} + +fn main() { + give_princess("teddy bear"); + give_princess("snake"); +} diff --git a/examples/error/error_vs_absence/input.md b/examples/error/error_vs_absence/input.md new file mode 100644 index 0000000000..ab89d3e7b4 --- /dev/null +++ b/examples/error/error_vs_absence/input.md @@ -0,0 +1,23 @@ +Previously, we have used the type `Option` to annotate that absense is a possibility. This +absense sometimes appears as an error, for example when `None` is unwrapped. In the more +general case where there may be multiple failure points for a multitude of different reasons, +an `Option` can be replaced by the more general `Result` type. A `Result` has these +variants: + +* `Ok`: An element `T` was found +* `Err`: An error was found with element `E` + +Similar to `Option`, `Result` also contains the `unwrap()` method which yields the element +`T` or calls `panic!()`. So far, this should seem similar to `Option`: + +{result.play} + +Clearly, panicking on an `Err` leaves an unhelpful error message. Do we even know anything +about libcore that the error is telling us all about? There must be a better way. + + +### See also: + +[`Result`][result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html diff --git a/examples/error/error_vs_absence/result.rs b/examples/error/error_vs_absence/result.rs new file mode 100644 index 0000000000..0307602d91 --- /dev/null +++ b/examples/error/error_vs_absence/result.rs @@ -0,0 +1,14 @@ +fn double_number(number_str: &str) -> i32 { + // It might not always be possible to parse a string into the other type + // so `parse()` returns a `Result` indicating possible failure. Let's + // just try `unwrap()` to get the number out. Will it bite us? + 2 * number_str.parse::().unwrap() +} + +fn main() { + let twenty = double_number("10"); + println!("double is {}", twenty); + + let tt = double_number("t"); + println!("double is {}", tt); +} diff --git a/examples/error/input.md b/examples/error/input.md new file mode 100644 index 0000000000..aa4bb37d4e --- /dev/null +++ b/examples/error/input.md @@ -0,0 +1,16 @@ +Error handling is the process of handling the possibility of failure. For example, failing to +read a file and then continuing to use that *bad* input regardless clearly would be problematic. +Error handling allows us to notice and handle those errors in some explicit fashion, saving the +rest of the program from pollution. + +The simplest error handling mechanism we will see is the `panic`; it prints an error message, +starts unwinding the task, and usually exits the program. Consider the following example: + +{error.play} + +This easily shows that we can induce program failure at will but it has a problem: what happens +if the princess is *not* given a gift? Technically, we *could* explicitly test this with a check +against the null string (`""`) the same way as with the snake however this is not reliable. The +problem is that programmers do not habitually make these checks unless required by the compiler. +In order for this to always be reliable, we require the compiler to point out the cases where there +may not be a gift. `str` does not do that for us; we require something else called `Option`. diff --git a/examples/error/limits_of_strings/input.md b/examples/error/limits_of_strings/input.md new file mode 100644 index 0000000000..5bc09e9f51 --- /dev/null +++ b/examples/error/limits_of_strings/input.md @@ -0,0 +1,27 @@ +We have been using `Strings` as errors for a while. In fact, this is somewhat limiting as +an error type. Below are the criteria for a good error type. `String` nicely fulfills the first +two but not the second two: + +* Represents different errors with the same type +* Presents nice error messages to the user +* Is easily type comparable. Consider comparing these two types: + - `Err("Please use a vector with at least one element".to_owned())` + - `Err(EmptyVec)` +* Can hold information about the error. Compare: + - `Err("+ cannot be used here".to_owned())` + - `Err(BadChar(c, position))` + +This makes `String` errors both difficult to react to and verbose to create. In fact, a nice +looking error message has nothing to do with how the type is structured. It is simply a +consequence of `Display` being implemented for the type. It should not be necessary to +pollute logic heavy code with `String` formatting simply for nice error messages. + +{rethink.play} + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[inplace]: /error/option_with_result/result_string_errors.html diff --git a/examples/error/limits_of_strings/rethink.rs b/examples/error/limits_of_strings/rethink.rs new file mode 100644 index 0000000000..60392e47b9 --- /dev/null +++ b/examples/error/limits_of_strings/rethink.rs @@ -0,0 +1,59 @@ +use std::num::ParseIntError; +use std::fmt; + +type Result = std::result::Result; + +#[derive(Debug)] +// Define our error types. These may be customized however is useful for our error +// handling cases. Now we will be able to defer to the underlying tools error +// implementation, write our own errors, or something in between. +enum DoubleError { + // We don't require any extra info to detail this error. + EmptyVec, + // We will defer to the parse error implementation for their error. Supplying extra + // info would require adding more data to the type. + Parse(ParseIntError), +} + +// How the type is displayed is completely separate from where the errors are generated. +// We do not need to be concerned that the display style will clutter the complex logic +// our utility requires. They are separate matters which are handled separately. +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Error: {}", match *self { + DoubleError::EmptyVec => + "please use a vector with at least one element".to_owned(), + // We didn't store extra info about the error. If we had desired, for + // example, to state which string failed to parse then we can't without + // modifying our type to carry that information. + DoubleError::Parse(ref e) => e.to_string(), + }) + } +} + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Change the error to our new type. + .ok_or(DoubleError::EmptyVec) + .and_then(|s| s.parse::() + // Update to the new error type here also. + .map_err(DoubleError::Parse) + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("{}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} diff --git a/examples/error/map/input.md b/examples/error/map/input.md new file mode 100644 index 0000000000..e6018867e3 --- /dev/null +++ b/examples/error/map/input.md @@ -0,0 +1,22 @@ +Like before, `match` is a valid method for handling an `Option` however you may find that this +gets tedious with heavy usage of `Options`. Luckily, there is an easier way. + +Consider the example below and in particular `peel()` and `chop()`; since each of these +operations is only valid when the input exists, it seems sensible that bad input simply means +the result is bad. This results in the simplistic mapping `Some -> Some` and `None -> None`. +This is actually so common that there is a built in method for it called `map()` which is +already implemented on `Option`. + +The result of this is that `chop()` is simpler to write than any of the previous methods. +Furthermore, the ability to chain these together makes it even more flexible; `process()` +easily can replace all the previous functions and still be compact. + +{map.play} + +[option]: http://doc.rust-lang.org/std/option/enum.Option.html + +### See also: + +[`struct`s][structs] + +[structs]: /custom_types/structs.html diff --git a/examples/error/map/map.rs b/examples/error/map/map.rs new file mode 100644 index 0000000000..1db9ee57ff --- /dev/null +++ b/examples/error/map/map.rs @@ -0,0 +1,60 @@ +#![allow(dead_code)] + +#[derive(Debug)] enum Food { Apple, Carrot, Potato } + +#[derive(Debug)] struct Peeled(Food); +#[derive(Debug)] struct Chopped(Food); +#[derive(Debug)] struct Cooked(Food); + +// Peeling food. If there isn't any, then just return `None`. +// Otherwise, return the peeled food. +fn peel(food: Option) -> Option { + match food { + Some(food) => Some(Peeled(food)), + None => None, + } +} + +// Similarly, we still need to keep track of whether there is a problem. If there +// is, we just pass it on. +fn chop(peeled: Option) -> Option { + match peeled { + Some(Peeled(food)) => Some(Chopped(food)), + None => None, + } +} + +// Same as before, when `Some`, pass `food` to `Cooked`, otherwise return `None`. +fn cook(chopped: Option) -> Option { + chopped.map(|Chopped(food)| Cooked(food)) +} + +// You could even simplify the process further +fn process(food: Option) -> Option { + food.map(|f| Peeled(f)) + .map(|Peeled(f)| Chopped(f)) + .map(|Chopped(f)| Cooked(f)) +} + +// Can we eat it now? +fn eat(food: Option) { + match food { + Some(food) => println!("Mmm. I love {:?}", food), + None => println!("Oh no! It wasn't edible."), + } +} + +fn main() { + let apple = Some(Food::Apple); + let carrot = Some(Food::Carrot); + let potato = None; + + let cooked_apple = cook(chop(peel(apple))); + let cooked_carrot = cook(chop(peel(carrot))); + // Let's try the simpler looking `process()` now. + let cooked_potato = process(potato); + + eat(cooked_apple); + eat(cooked_carrot); + eat(cooked_potato); +} diff --git a/examples/error/more_combinators/combinators.rs b/examples/error/more_combinators/combinators.rs new file mode 100644 index 0000000000..056ec343f0 --- /dev/null +++ b/examples/error/more_combinators/combinators.rs @@ -0,0 +1,53 @@ +#![allow(dead_code)] + +#[derive(Debug)] enum Food { CordonBleu, Steak, Sushi } +#[derive(Debug)] enum Day { Monday, Tuesday, Wednesday } + +// We don't have the ingredients to make Sushi. +fn have_ingredients(food: Food) -> Option { + match food { + Food::Sushi => None, + _ => Some(food), + } +} + +// We know how to make everything except Cordon Bleu. +fn can_cook(food: Food) -> Option { + match food { + Food::CordonBleu => None, + _ => Some(food), + } +} + +// To make a meal, we require both the ingredients and the ability to make that +// meal, which is only possible when both are true; thus successes chain. +// Conveniently, this can be rewritten more compactly with `and_then()`. +fn cookable_v1(food: Food) -> Option { + match have_ingredients(food) { + None => None, + Some(food) => match can_cook(food) { + None => None, + Some(food) => Some(food), + }, + } +} + +// Same as `v1` above but uses `and_then()` instead. +fn cookable_v2(food: Food) -> Option { + have_ingredients(food).and_then(can_cook) +} + +fn eat(food: Food, day: Day) { + match cookable_v2(food) { + Some(food) => println!("Yay! On {:?} we get to eat {:?}.", day, food), + None => println!("Oh no. We don't get to eat on {:?}?", day), + } +} + +fn main() { + let (cordon_bleu, steak, sushi) = (Food::CordonBleu, Food::Steak, Food::Sushi); + + eat(cordon_bleu, Day::Monday); + eat(steak, Day::Tuesday); + eat(sushi, Day::Wednesday); +} diff --git a/examples/error/more_combinators/input.md b/examples/error/more_combinators/input.md new file mode 100644 index 0000000000..2c733af5d5 --- /dev/null +++ b/examples/error/more_combinators/input.md @@ -0,0 +1,30 @@ +`map()` was previously described as a way to simplify a `match` which also allows chaining. +However, `map()` does not work for all cases because the constituents often occur in many +different combinations. Consider the following example: + +{combinators.play} + +The reason this worked is because `and_then()` happened to require the exact function type as an +input that was needed here. `map()` did not. Comparing the signatures of their input types, you +will see that when the function returned an `Option`, `and_then()` became the one and *only* +valid choice. + +```rust +map(): FnOnce(T) -> U +and_then(): FnOnce(T) -> Option +``` + +These are just two of many different combinators that are implemented on +[`Option`][option] by the std library for many different use cases. It is advantageous +to become familiar with them because they can simplify many error handling procedures and +avoid the ugly and suicidal `panic!()` alternative. The other common error handling type, +`Result`, also uses most of these same constructs so the skills are transferable. + + +### See also: + +[`Option`][option], [`Option::map()`][map], and [`Option::and_then()`][and_then] + +[option]: http://doc.rust-lang.org/std/option/enum.Option.html +[map]: http://doc.rust-lang.org/std/option/enum.Option.html#method.map +[and_then]: http://doc.rust-lang.org/std/option/enum.Option.html#method.and_then diff --git a/examples/error/option_with_result/combinator_combinations/input.md b/examples/error/option_with_result/combinator_combinations/input.md new file mode 100644 index 0000000000..b7d1cb76c0 --- /dev/null +++ b/examples/error/option_with_result/combinator_combinations/input.md @@ -0,0 +1,15 @@ +What if multiple `Results` needed to interact together? Is it still reasonably convenient? +It turns out, not really. + +{result_try.play} + +What is happening is this approach tries to work with the data without ever removing the `Ok` +wrapper on it. Sometimes it is a good approach but in this case it is really awkward. What if +we could `unwrap` it without possibly inducing `panic`? That is where we are headed next. + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/option_with_result/combinator_combinations/result_try.rs new file mode 100644 index 0000000000..7ad2136661 --- /dev/null +++ b/examples/error/option_with_result/combinator_combinations/result_try.rs @@ -0,0 +1,49 @@ +use std::io::prelude::*; +use std::fs::File; + +type Result = std::result::Result; + +// Setup to make this work. Create two files with some info. +fn setup() { + // Ignore the return value because we don't care about it. + let _ = File::create("a") + .and_then(|mut file| file.write_all(b"grape")); + + let _ = File::create("b") + .and_then(|mut file| file.write_all(b"fruit")); +} + +// Get the data from each file with the data stored in a `Result`. +fn get_data(path: &str) -> Result { + File::open(path) + .map_err(|err| err.to_string()) + .and_then(|mut file| { + let mut contents = String::new(); + + // Read the data into `contents`. + file.read_to_string(&mut contents) + .map_err(|err| err.to_string()) + // Ignore the output `read_to_string` returns and return `contents`. + .map(|_| contents) + }) +} + +// Concat the contents of the two files together into a new `Result`. +fn concat(a: &str, b: &str) -> Result { + let (data_a, data_b) = (get_data(a), get_data(b)); + + data_a.and_then(|a| + // Return `Ok` when both `a` and `b` are `Ok`. Otherwise return + // whichever has the first `Err`. + data_b.and_then(|b| Ok(a + &b)) + ) +} + +fn main() { + setup(); + + match concat("a", "b") { + Ok(n) => println!("{}", n), + Err(e) => println!("Error: {:?}", e), + } +} diff --git a/examples/error/option_with_result/enter_try/input.md b/examples/error/option_with_result/enter_try/input.md new file mode 100644 index 0000000000..d1567430b3 --- /dev/null +++ b/examples/error/option_with_result/enter_try/input.md @@ -0,0 +1,26 @@ +The previous problem was awkward because avoiding `unwrap` forced us to nest deeper and +deeper when what we really wanted was to get the variable *out*. So, is there any way +to accomodate this approach without `panic`? Well, what is a valid action to take when +an `Err` is found? It turns out there are two: + +1. `panic!` which we already decided to try to avoid if possible +2. `return` because an `Err` means it cannot be handled + +This is exactly the purpose of `try!`; it is *almost*[^1] exactly equivalent to an +`unwrap` which `returns` instead of `panics` on `Errs`. + +{try.play} + +This really is a *huge* improvement but there is still the nagging issue of `map_err`. There is +actually a way to avoid it (we are using it everywhere it seems) but we are still missing some +details. First, we have to learn how to make better errors. + +[^1]: See [re-enter try!][re_enter_try] for more details. + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html +[re_enter_try]: /error/reenter_try.html diff --git a/examples/error/option_with_result/enter_try/try.rs b/examples/error/option_with_result/enter_try/try.rs new file mode 100644 index 0000000000..f163793acd --- /dev/null +++ b/examples/error/option_with_result/enter_try/try.rs @@ -0,0 +1,47 @@ +use std::io::prelude::*; +use std::fs::File; + +type Result = std::result::Result; + +// Setup to make this work. Create two files with some info. +fn setup() -> std::io::Result<()> { + let mut a = try!(File::create("a")); + try!(a.write_all(b"grape")); + + let mut b = try!(File::create("b")); + b.write_all(b"fruit") +} + +// Get the data from each file with the data stored in a `Result`. +fn get_data(path: &str) -> Result { + // `try` unwraps the value or returns the error. + let mut file = try!(File::open(path) + // Errors still must be converted to strings. + .map_err(|err| err.to_string()) + ); + let mut contents = String::new(); + + // Read the data into `contents`. + try!(file.read_to_string(&mut contents) + .map_err(|err| err.to_string()) + ); + + Ok(contents) +} + +// Concat the contents of the two files together into a new `Result`. +fn concat(a: &str, b: &str) -> Result { + let (data_a, data_b) = (try!(get_data(a)), try!(get_data(b))); + + Ok(data_a + &data_b) +} + +fn main() { + // Ignore this result. + let _ = setup(); + + match concat("a", "b") { + Ok(n) => println!("{}", n), + Err(e) => println!("Error: {:?}", e), + } +} diff --git a/examples/error/option_with_result/input.md b/examples/error/option_with_result/input.md new file mode 100644 index 0000000000..de52492598 --- /dev/null +++ b/examples/error/option_with_result/input.md @@ -0,0 +1,16 @@ +The previous examples have always been very convenient; a `Result` interacts with the same +`Results` and an `Option` with the same `Option`. Sometimes it is not this easy though; +`Options` and `Results` may have to interact or even `Result` with +`Result`. + +Here is an example where one returns an `Option` and the other returns an `Result`. Aside +from messy errors provided by `unwrap`, this looks reasonable: + +{option_result.play} + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/option_with_result/option_result.rs b/examples/error/option_with_result/option_result.rs new file mode 100644 index 0000000000..e6c34801f5 --- /dev/null +++ b/examples/error/option_with_result/option_result.rs @@ -0,0 +1,20 @@ +// The first attempt conveniently uses `unwrap` with the aforementioned +// bad errors it results in. +fn double_first(vec: Vec<&str>) -> i32 { + // What if the vector is empty? + let first = vec.first().unwrap(); + + // What if the element doesn't parse to a number? + 2 * first.parse::().unwrap() +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + println!("The first doubled is {}", double_first(numbers)); + println!("The first doubled is {}", double_first(empty)); + // ^ Comment out this line to see the second error. + println!("The first doubled is {}", double_first(strings)); +} diff --git a/examples/error/option_with_result/result_string_errors/input.md b/examples/error/option_with_result/result_string_errors/input.md new file mode 100644 index 0000000000..5c9f47b3f6 --- /dev/null +++ b/examples/error/option_with_result/result_string_errors/input.md @@ -0,0 +1,17 @@ +Eliminating `unwrap` from the previous example requires more care. The two types in play +being `Option` and `Result`, one valid approach would be to convert both into a `Result` +with a common `Err` type. We will try it with `Err(String)` which seems like a nice first +approximation: + +{result_string.play} + +This is not too bad but it is hardly as nice as the original (it can still be nicer but +we are not there yet). The question is, does this approach scale well. Consider the next +example. + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/option_with_result/result_string_errors/result_string.rs b/examples/error/option_with_result/result_string_errors/result_string.rs new file mode 100644 index 0000000000..3e2f454d3f --- /dev/null +++ b/examples/error/option_with_result/result_string_errors/result_string.rs @@ -0,0 +1,32 @@ +type Result = std::result::Result; + +fn double_first(vec: Vec<&str>) -> Result { + vec.first() + // Convert the `Option` to a `Result` if there is a value; otherwise + // use an `Err` containing this `String`. + .ok_or("Please use a vector with at least one element.".to_owned()) + // `parse` returns a `Result`. + .and_then(|s| s.parse::() + // The return type is `Result`. We need + // to map only the errors `parse` yields to `String`. + .map_err(|e| e.to_string()) + // Apply the double to the number inside. + .map(|i| 2 * i)) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("Error: {:?}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md new file mode 100644 index 0000000000..f12aac96ee --- /dev/null +++ b/examples/error/reenabling_box/input.md @@ -0,0 +1,41 @@ +We have seen that by implementing `Display` and `From` for our error type, we have enabled +usage of almost all of the std library error handling tools. That is, we missed one +capability: the ability to easily `box` our error type. + +Namely, the std library will automatically convert from any type which implements the +`Error` trait into the trait object `Box` via `From`. To a library user, this +conveniently allows the following: + +```rust +// Any error type automatically convertible to `Box` may be used here. +fn foo(...) -> Result> { ... } +``` + +For example, a user may use a variety of libraries which each provide their own error +types. In order to define a valid `Result` type, the user has a few choices: + +* define a new wrapper error type around the external libraries error types +* convert it to `String` or some other intermediate choice +* box it up into `Box` via type erasure + +Boxing it is a common choice. The only penalty is that the error type is only known +at runtime and not statically determined. All that needs to be done to enable this +is implement the `Error` trait: + +```rust +trait Error: Debug + Display { + fn description(&self) -> &str; + fn cause(&self) -> Option<&Error>; +} +``` + +By implementing this, our previous example would be just as valid when the error type +is `Box` as it was before with `DoubleError`. + +{rethink.play} + +### See also: + +[`Error` trait][error] + +[error]: http://doc.rust-lang.org/std/error/trait.Error.html diff --git a/examples/error/reenabling_box/rethink.rs b/examples/error/reenabling_box/rethink.rs new file mode 100644 index 0000000000..5f729a5ea3 --- /dev/null +++ b/examples/error/reenabling_box/rethink.rs @@ -0,0 +1,75 @@ +use std::error; +use std::fmt; +use std::num::ParseIntError; + +// Change the alias to `Box`. +type Result = std::result::Result>; + +#[derive(Debug)] +enum DoubleError { + EmptyVec, + Parse(ParseIntError), +} + +impl From for DoubleError { + fn from(err: ParseIntError) -> DoubleError { + DoubleError::Parse(err) + } +} + +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Error: {}", match *self { + DoubleError::EmptyVec => + "please use a vector with at least one element".to_owned(), + DoubleError::Parse(ref e) => e.to_string(), + }) + } +} + +impl error::Error for DoubleError { + fn description(&self) -> &str { + match *self { + // Trying to use `Display` here results in the string being immediately + // dropped which won't compile so we have to write out the phrase again. + DoubleError::EmptyVec => "please use a vector with at least one element", + // This already impls `Error`, so defer to its implementation. + DoubleError::Parse(ref err) => err.description(), + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + // No underlying cause so return `None`. + DoubleError::EmptyVec => None, + // The cause is the underlying implementation error type. Is implicitly + // cast to the trait object `&error::Error`. This works because the + // underlying type already implements the `Error` trait. + DoubleError::Parse(ref e) => Some(e), + } + } +} + +fn double_first(vec: Vec<&str>) -> Result { + let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); + let parsed = try!(first.parse::()); + + Ok(2 * parsed) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("{}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} diff --git a/examples/error/reenter_try/input.md b/examples/error/reenter_try/input.md new file mode 100644 index 0000000000..0be7b70058 --- /dev/null +++ b/examples/error/reenter_try/input.md @@ -0,0 +1,42 @@ +If you will notice from the previous example, when we call `parse`, the immediate reaction +is to `map` the error from a library error into our new custom error type. + +```rust +.and_then(|s| s.parse::() + .map_err(DoubleError::Parse) +``` + +This is a very simple and also common operation so it would be convenient if eliding it +would work but alas, it does not. `and_then` is not sufficiently flexible that it can handle +this; `try!` is though. + +`try!` has previously been explained as either `unwrap` or `return Err(err)` which is only +`93%` correct. It actually means `unwrap` or `return Err(From::from(err))`. Since `From::from` +is a conversion utility between different types, this means if you `try!` something where the +error is convertible to the return type, it will convert automatically. This means, if we +rewrite this example with `try!` when `From::from` is implemented for our error type, +the `map_err` will go away: + +{rethink.play} + +This is actually fairly clean now. If you compare it with the original `panic`, it is very similar +to replacing the `unwrap` calls with `try!` except that the return types are `Result` and so +they must be destructured at the top level. + +However, do not expect error handling of this sort to replace all usage of `unwrap` in +practice. Error handling of this sort tripled our code line count and cannot really be +called simple even if this is heavily biased by the small code size. Indeed, moving a 1000 line +library from `unwrap` to more proper error handling might be feasible in an additional +100 lines of code though the necessary refractoring definitely would not be trivial. + +This is a very reasonable place to be. Many libraries might get away with only +implementing `Display` and then adding `From` on an as needed basis. A serious library +though will have users with certain expections about how it should implement error handling. +In those cases, the error handling will need to be taken one step further. + +### See also: + +[`From::from`][from] and [`try!`][try] + +[from]: http://doc.rust-lang.org/std/convert/trait.From.html +[try]: http://doc.rust-lang.org/std/macro.try!.html diff --git a/examples/error/reenter_try/rethink.rs b/examples/error/reenter_try/rethink.rs new file mode 100644 index 0000000000..b1e1c9d0d9 --- /dev/null +++ b/examples/error/reenter_try/rethink.rs @@ -0,0 +1,56 @@ +use std::num::ParseIntError; +use std::fmt; + +type Result = std::result::Result; + +#[derive(Debug)] +enum DoubleError { + EmptyVec, + Parse(ParseIntError), +} + +// Implement the conversion from `ParseIntError` to `DoubleError`. This will be +// automatically called by `try!` if a `ParseIntError` needs converting into +// a `DoubleError`. +impl From for DoubleError { + fn from(err: ParseIntError) -> DoubleError { + DoubleError::Parse(err) + } +} + +impl fmt::Display for DoubleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Error: {}", match *self { + DoubleError::EmptyVec => + "please use a vector with at least one element".to_owned(), + DoubleError::Parse(ref e) => e.to_string(), + }) + } +} + +// The same structure as before but rather than chain all `Results` +// and `Options` along, we `try!` to get the inner value out immediately. +fn double_first(vec: Vec<&str>) -> Result { + // Still convert to `Result` by stating how to convert `None`. + let first = try!(vec.first().ok_or(DoubleError::EmptyVec)); + let parsed = try!(first.parse::()); + + Ok(2 * parsed) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("The first doubled is {}", n), + Err(e) => println!("{}", e), + } +} + +fn main() { + let numbers = vec!["93", "18"]; + let empty = vec![]; + let strings = vec!["tofu", "93", "18"]; + + print(double_first(numbers)); + print(double_first(empty)); + print(double_first(strings)); +} diff --git a/examples/error/result_alias/alias.rs b/examples/error/result_alias/alias.rs new file mode 100644 index 0000000000..c75b8675b0 --- /dev/null +++ b/examples/error/result_alias/alias.rs @@ -0,0 +1,23 @@ +use std::num::ParseIntError; +use std::result; + +// A generic alias for any `Result` with this specific `Err` type. +type Result = result::Result; + +// Use the alias defined above referring to our specific `Result` type. +fn double_number(number_str: &str) -> Result { + number_str.parse::().map(|n| 2 * n) +} + +// Again, the alias saved us from defining it again. +fn print(result: Result) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {:?}", e), + } +} + +fn main() { + print(double_number("10")); + print(double_number("t")); +} diff --git a/examples/error/result_alias/input.md b/examples/error/result_alias/input.md new file mode 100644 index 0000000000..cb4657b974 --- /dev/null +++ b/examples/error/result_alias/input.md @@ -0,0 +1,16 @@ +What if the specific `Result` type is reused many many times? Then quickly it becomes tedious +to write out the full type name. Instead, a generic alias for the specific `Result` may be +defined. + +{alias.play} + +This is particularly helpful at a module level because all errors found in a specific module +may have the same `Err` type; a single alias succinctly defines *all* module `Results`. This +is so useful that the std library even supplies one: `io::Result` which refers to IO errors. + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result_map/input.md b/examples/error/result_map/input.md new file mode 100644 index 0000000000..6af4fcbc89 --- /dev/null +++ b/examples/error/result_map/input.md @@ -0,0 +1,21 @@ +To avoid the `unwrap()` in the previous example, we will have to rewrite the example to be +specific about what type it returns. In this case, the regular element should definitely +be `i32` but what about the `Err` type? Well, `parse()` is implemented with the +[`FromStr trait`][from_str] for [`i32`][i32]. That implementation specifies the +`Err` type as [`ParseIntError`][parse_int_error]. + +{result.play} + +Similar to `Option`, `Result` has many other combinators besides `map` such as `and_then` +and `unwrap_or`; even ones to handle the errors specifically such as `map_err`. +`Result` contains the complete listing. + +### See also: + +[`i32`][i32], [`FromStr`][from_str], [`ParseIntErr`][parse_int_error], and +[`Result`][result] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html +[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html +[i32]: http://doc.rust-lang.org/std/primitive.i32.html diff --git a/examples/error/result_map/result.rs b/examples/error/result_map/result.rs new file mode 100644 index 0000000000..f19441c216 --- /dev/null +++ b/examples/error/result_map/result.rs @@ -0,0 +1,34 @@ +use std::num::ParseIntError; + +// With the return type rewritten, we proceed to use pattern matching without +// `unwrap()` but it is tedious. Couldn't a combinator like in the `Option` +// example also be used here? Yes. +fn double_number(number_str: &str) -> Result { + match number_str.parse::() { + Ok(n) => Ok(2 * n), + Err(e) => Err(e), + } +} + +// The exact same but written with `map()`. Modify if the value is valid, +// otherwise pass the error on. +fn double_number_map(number_str: &str) -> Result { + number_str.parse::().map(|n| 2 * n) +} + +fn print(result: Result) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {:?}", e), + } +} + +fn main() { + // Still presents a reasonable answer. + let twenty = double_number("10"); + print(twenty); + + // This is now much better than before with the messy `panic`. + let tt = double_number_map("t"); + print(tt); +} diff --git a/examples/error/unwrap/input.md b/examples/error/unwrap/input.md new file mode 100644 index 0000000000..921a8b6616 --- /dev/null +++ b/examples/error/unwrap/input.md @@ -0,0 +1,23 @@ +We determined a snake is an inappropriate gift for a princess. What if she expected a gift +but did not receive one? Clearly that would be just as bad but how would it be handled? Well, +`Option` is the type which is used when absense is a possibility. This manifests itself as +two choices: + +* `Some`: An element `T` was found +* `None`: No element was found + +These can either be explicitly handled via `match` or implicitly with `unwrap`. `unwrap`, +deferring to the std library, either returns the inner element or `panics`. Regardless of +explicit or implicit handling, an `enum` such as `Option` will have all cases handled. The +compiler ensures that none are forgotten giving us more confidence in its robustness. + +{unwrap.play} + +As you can see, direct control yielded an even nicer result than the original `panic` along +with the choice to `panic` if we desired. `unwrap` on the other hand, deferring to the std +library left us with the most generic and unhelpful: "I unwrapped a `None`!" meanwhile yielding +the good results the rest of the time. A more meaningful message will require a better approach[^1]. + +[^1]: ignoring [expect][expect] which allows manual customization of the `panic` for now + +[expect]: http://doc.rust-lang.org/std/option/enum.Option.html#method.expect diff --git a/examples/error/unwrap/unwrap.rs b/examples/error/unwrap/unwrap.rs new file mode 100644 index 0000000000..d0d772ae7b --- /dev/null +++ b/examples/error/unwrap/unwrap.rs @@ -0,0 +1,36 @@ +// The commoner cannot bring down the task which precludes the option of `panic`. +// These must all be handled manually. `match` would be the correct approach. +fn give_commoner(gift: Option<&str>) { + // Specify a specific course of action for each case. + match gift { + Some("snake") => println!("Yuck! Throws the snake in the fire."), + Some(inner) => println!("{}! How nice.", inner), + None => println!("No gift? Oh well."), + } +} + +// A princess is allowed to bring down the task at will so `panic` is an option. +fn give_princess(gift: Option<&str>) { + // Using `unwrap` defers the case analysis to the std library which will + // `panic` when it receives a `None`. + let inside = gift.unwrap(); + if inside == "snake" { panic!("AAAaaaaa!!!!"); } + + println!("I love {}s!!!!!", inside); +} + +fn main() { + let food = Some("chicken"); + let snake = Some("snake"); + let void = None; + + give_commoner(food); + give_commoner(snake); + give_commoner(void); + + let bird = Some("robin"); + let nothing = None; + + give_princess(bird); + give_princess(nothing); +} diff --git a/examples/structure.json b/examples/structure.json index d8eadab57b..33ac2d98b4 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -142,6 +142,22 @@ { "id": "iter", "title": "Iterators", "children": null }, { "id": "clone", "title": "Clone", "children": null } ] }, + { "id": "error", "title": "Error handling", "children": [ + { "id": "unwrap", "title": "Option & unwrap", "children": null }, + { "id": "map", "title": "map", "children": null }, + { "id": "more_combinators", "title": "More combinators", "children": null }, + { "id": "error_vs_absence", "title": "Errors vs Absence", "children": null }, + { "id": "result_map", "title": "map for Result", "children": null }, + { "id": "result_alias", "title": "Result as an alias", "children": null }, + { "id": "option_with_result", "title": "Options with Results", "children": [ + { "id": "result_string_errors", "title": "Errors as strings", "children": null }, + { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null }, + { "id": "enter_try", "title": "Enter try!", "children": null } + ] }, + { "id": "limits_of_strings", "title": "The limits of strings", "children": null }, + { "id": "reenter_try", "title": "Re-enter try!", "children": null }, + { "id": "reenabling_box", "title": "Re-enabling box", "children": null } + ] }, { "id": "std", "title": "Std library types", "children": [ { "id": "box", "title": "Box, stack and heap", "children": null }, { "id": "vec", "title": "Vectors", "children": null }, From 2bc97255887113054dd0d52bdf221bda716edee1 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 2 Dec 2015 14:51:07 -0500 Subject: [PATCH 0367/1122] Fix some error handling nits --- .../combinator_combinations/result_try.rs | 14 ++++++++------ examples/error/option_with_result/enter_try/try.rs | 2 +- examples/error/reenabling_box/input.md | 9 +++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/option_with_result/combinator_combinations/result_try.rs index 7ad2136661..a56ab7adb0 100644 --- a/examples/error/option_with_result/combinator_combinations/result_try.rs +++ b/examples/error/option_with_result/combinator_combinations/result_try.rs @@ -3,14 +3,16 @@ use std::fs::File; type Result = std::result::Result; -// Setup to make this work. Create two files with some info. +// Setup to make this work. Create two files with some info. Ignore the +// return values because we don't care about them here. fn setup() { - // Ignore the return value because we don't care about it. - let _ = File::create("a") - .and_then(|mut file| file.write_all(b"grape")); + File::create("a") + .and_then(|mut file| file.write_all(b"grape")) + .unwrap(); - let _ = File::create("b") - .and_then(|mut file| file.write_all(b"fruit")); + File::create("b") + .and_then(|mut file| file.write_all(b"fruit")) + .unwrap(); } // Get the data from each file with the data stored in a `Result`. diff --git a/examples/error/option_with_result/enter_try/try.rs b/examples/error/option_with_result/enter_try/try.rs index f163793acd..3f946b93ee 100644 --- a/examples/error/option_with_result/enter_try/try.rs +++ b/examples/error/option_with_result/enter_try/try.rs @@ -38,7 +38,7 @@ fn concat(a: &str, b: &str) -> Result { fn main() { // Ignore this result. - let _ = setup(); + setup().unwrap(); match concat("a", "b") { Ok(n) => println!("{}", n), diff --git a/examples/error/reenabling_box/input.md b/examples/error/reenabling_box/input.md index f12aac96ee..ed826e6c43 100644 --- a/examples/error/reenabling_box/input.md +++ b/examples/error/reenabling_box/input.md @@ -18,9 +18,9 @@ types. In order to define a valid `Result` type, the user has a few choice * convert it to `String` or some other intermediate choice * box it up into `Box` via type erasure -Boxing it is a common choice. The only penalty is that the error type is only known -at runtime and not statically determined. All that needs to be done to enable this -is implement the `Error` trait: +Boxing it is a common choice. The only penalty is that the underlying error type is only known +at runtime and not [statically determined][dynamic_dispatch]. All that needs to be done to enable +this is implement the `Error` trait: ```rust trait Error: Debug + Display { @@ -36,6 +36,7 @@ is `Box` as it was before with `DoubleError`. ### See also: -[`Error` trait][error] +[Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] +[dynamic_dispatch]: http://doc.rust-lang.org/book/trait-objects.html#dynamic-dispatch [error]: http://doc.rust-lang.org/std/error/trait.Error.html From ca115b8ff0f58b4254fdb244c66bb2f66f969b3e Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 3 Dec 2015 21:48:33 -0500 Subject: [PATCH 0368/1122] Debug to Display. Move `Error:` to outer level. Move some comments around. Recurse into fmt instead of calling to_string --- examples/error/limits_of_strings/rethink.rs | 21 ++++++++++-------- .../combinator_combinations/result_try.rs | 2 +- .../error/option_with_result/enter_try/try.rs | 2 +- .../result_string_errors/result_string.rs | 2 +- examples/error/reenabling_box/rethink.rs | 22 +++++++++---------- examples/error/reenter_try/rethink.rs | 12 +++++----- examples/error/result_alias/alias.rs | 2 +- examples/error/result_map/result.rs | 2 +- 8 files changed, 34 insertions(+), 31 deletions(-) diff --git a/examples/error/limits_of_strings/rethink.rs b/examples/error/limits_of_strings/rethink.rs index 60392e47b9..868dc69a4f 100644 --- a/examples/error/limits_of_strings/rethink.rs +++ b/examples/error/limits_of_strings/rethink.rs @@ -18,16 +18,19 @@ enum DoubleError { // How the type is displayed is completely separate from where the errors are generated. // We do not need to be concerned that the display style will clutter the complex logic // our utility requires. They are separate matters which are handled separately. +// +// We don't store extra info about the errors. If we had desired, for example, to state +// which string failed to parse then we can't without modifying our types to carry that +// information accordingly. impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Error: {}", match *self { - DoubleError::EmptyVec => - "please use a vector with at least one element".to_owned(), - // We didn't store extra info about the error. If we had desired, for - // example, to state which string failed to parse then we can't without - // modifying our type to carry that information. - DoubleError::Parse(ref e) => e.to_string(), - }) + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + // This is a wrapper so defer to the underlying types' own implementation + // of `fmt`. + DoubleError::Parse(ref e) => e.fmt(f), + } } } @@ -44,7 +47,7 @@ fn double_first(vec: Vec<&str>) -> Result { fn print(result: Result) { match result { Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("{}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/option_with_result/combinator_combinations/result_try.rs index a56ab7adb0..738048a815 100644 --- a/examples/error/option_with_result/combinator_combinations/result_try.rs +++ b/examples/error/option_with_result/combinator_combinations/result_try.rs @@ -46,6 +46,6 @@ fn main() { match concat("a", "b") { Ok(n) => println!("{}", n), - Err(e) => println!("Error: {:?}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/option_with_result/enter_try/try.rs b/examples/error/option_with_result/enter_try/try.rs index 3f946b93ee..394a21c530 100644 --- a/examples/error/option_with_result/enter_try/try.rs +++ b/examples/error/option_with_result/enter_try/try.rs @@ -42,6 +42,6 @@ fn main() { match concat("a", "b") { Ok(n) => println!("{}", n), - Err(e) => println!("Error: {:?}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/option_with_result/result_string_errors/result_string.rs b/examples/error/option_with_result/result_string_errors/result_string.rs index 3e2f454d3f..dbf9fa85c8 100644 --- a/examples/error/option_with_result/result_string_errors/result_string.rs +++ b/examples/error/option_with_result/result_string_errors/result_string.rs @@ -17,7 +17,7 @@ fn double_first(vec: Vec<&str>) -> Result { fn print(result: Result) { match result { Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("Error: {:?}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/reenabling_box/rethink.rs b/examples/error/reenabling_box/rethink.rs index 5f729a5ea3..44dfdbca05 100644 --- a/examples/error/reenabling_box/rethink.rs +++ b/examples/error/reenabling_box/rethink.rs @@ -19,22 +19,22 @@ impl From for DoubleError { impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Error: {}", match *self { - DoubleError::EmptyVec => - "please use a vector with at least one element".to_owned(), - DoubleError::Parse(ref e) => e.to_string(), - }) + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + DoubleError::Parse(ref e) => e.fmt(f), + } } } impl error::Error for DoubleError { fn description(&self) -> &str { match *self { - // Trying to use `Display` here results in the string being immediately - // dropped which won't compile so we have to write out the phrase again. - DoubleError::EmptyVec => "please use a vector with at least one element", - // This already impls `Error`, so defer to its implementation. - DoubleError::Parse(ref err) => err.description(), + // A very short description of the error. Doesn't need to be the + // same as `Display`. + DoubleError::EmptyVec => "empty vectors not allowed", + // This already impls `Error`, so defer to its own implementation. + DoubleError::Parse(ref e) => e.description(), } } @@ -60,7 +60,7 @@ fn double_first(vec: Vec<&str>) -> Result { fn print(result: Result) { match result { Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("{}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/reenter_try/rethink.rs b/examples/error/reenter_try/rethink.rs index b1e1c9d0d9..38533ce91c 100644 --- a/examples/error/reenter_try/rethink.rs +++ b/examples/error/reenter_try/rethink.rs @@ -20,11 +20,11 @@ impl From for DoubleError { impl fmt::Display for DoubleError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Error: {}", match *self { - DoubleError::EmptyVec => - "please use a vector with at least one element".to_owned(), - DoubleError::Parse(ref e) => e.to_string(), - }) + match *self { + DoubleError::EmptyVec => + write!(f, "please use a vector with at least one element"), + DoubleError::Parse(ref e) => e.fmt(f), + } } } @@ -41,7 +41,7 @@ fn double_first(vec: Vec<&str>) -> Result { fn print(result: Result) { match result { Ok(n) => println!("The first doubled is {}", n), - Err(e) => println!("{}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/result_alias/alias.rs b/examples/error/result_alias/alias.rs index c75b8675b0..dd9a8ade10 100644 --- a/examples/error/result_alias/alias.rs +++ b/examples/error/result_alias/alias.rs @@ -13,7 +13,7 @@ fn double_number(number_str: &str) -> Result { fn print(result: Result) { match result { Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {:?}", e), + Err(e) => println!("Error: {}", e), } } diff --git a/examples/error/result_map/result.rs b/examples/error/result_map/result.rs index f19441c216..6f7a741837 100644 --- a/examples/error/result_map/result.rs +++ b/examples/error/result_map/result.rs @@ -19,7 +19,7 @@ fn double_number_map(number_str: &str) -> Result { fn print(result: Result) { match result { Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {:?}", e), + Err(e) => println!("Error: {}", e), } } From cee6e69c22cffc1a3c3dcfc9f02d9486cfdd3745 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 14 Dec 2015 15:14:11 -0500 Subject: [PATCH 0369/1122] Small readme fix This is mostly to redeploy the site, because I screwed up. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f2b8b496c..e73b92dbf9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -[![Build Status][travis-image]][travis-link] # Rust by Example +[![Build Status][travis-image]][travis-link] + ## What's this? This is the source code of the [Rust by Example][website] website! From 913c5ac7e80ec921f07254237140ed145d68fd1e Mon Sep 17 00:00:00 2001 From: Jordan Danford Date: Mon, 14 Dec 2015 18:10:45 -0700 Subject: [PATCH 0370/1122] hello/comment: fix typo --- examples/hello/comment/comment.rs | 8 ++++---- examples/hello/comment/input.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/hello/comment/comment.rs b/examples/hello/comment/comment.rs index 78921d78bf..50e026f9c1 100644 --- a/examples/hello/comment/comment.rs +++ b/examples/hello/comment/comment.rs @@ -6,20 +6,20 @@ fn main() { // println!("Hello, world!"); // Run it. See? Now try deleting the two slashes, and run it again. - + /* * This is another type of comment, the block comment. In general, * the line comment is the recommended comment style however the * block comment is extremely useful for debugging */ - + /* Note, the previous column of `*` was entirely for style. There's no actual need for it. */ - + // Observe how block comments allow easy expression manipulation - // which line comments do not. Deleting the comment deliminators + // which line comments do not. Deleting the comment delimiters // will change the result: let x = 5 + /* 90 + */ 5; println!("Is `x` 10 or 100? x = {}", x); diff --git a/examples/hello/comment/input.md b/examples/hello/comment/input.md index 609d0290d5..7399fbfbfb 100644 --- a/examples/hello/comment/input.md +++ b/examples/hello/comment/input.md @@ -3,7 +3,7 @@ a few different varieties: * *Regular comments* which are ignored by the compiler: - `// Line comments which go to the end of the line.` - - `/* Block comments which go to the closing deliminator. */` + - `/* Block comments which go to the closing delimiter. */` * *Doc comments* which are parsed into HTML library [documentation][docs]: - `/// Generate library docs for the following item.` From 5621ed96da0b61bdcd7090dbd682b2938c831342 Mon Sep 17 00:00:00 2001 From: Jordan Danford Date: Mon, 14 Dec 2015 18:10:50 -0700 Subject: [PATCH 0371/1122] std_misc/channels: fix typo --- examples/std_misc/channels/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/std_misc/channels/input.md b/examples/std_misc/channels/input.md index 86ac3fb69f..a7edabc1a5 100644 --- a/examples/std_misc/channels/input.md +++ b/examples/std_misc/channels/input.md @@ -1,5 +1,5 @@ Rust provides asynchronous `channels` for communication between threads. Channels -allow an unidirectional flow of information between two end-points: the +allow a unidirectional flow of information between two end-points: the `Sender` and the `Receiver`. {channels.play} From 37b35572dd1fad734ace204afd061ab8486d8823 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 13:24:52 -0800 Subject: [PATCH 0372/1122] Added description of `@` In the book, this is explicitly stated. In rustbyexample, confusion may occur without thorough reading of the code --- examples/flow_control/match/binding/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/flow_control/match/binding/input.md b/examples/flow_control/match/binding/input.md index 005962df40..a19cec663e 100644 --- a/examples/flow_control/match/binding/input.md +++ b/examples/flow_control/match/binding/input.md @@ -1,6 +1,6 @@ Indirectly accessing a variable makes it impossible to branch and use that -variable without re-binding. `match` provides the `@` sigil for exactly -this purpose: +variable without re-binding. `match` provides the `@` sigil for binding values to +names: {binding.play} From 0fe1209db63a93f0ef7c609dc4dc9eb676bf63e0 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 13:38:07 -0800 Subject: [PATCH 0373/1122] Removed redundancies and added clarification --- examples/flow_control/if_let/if_let.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/flow_control/if_let/if_let.rs b/examples/flow_control/if_let/if_let.rs index eb96cb6c42..121ce9b721 100644 --- a/examples/flow_control/if_let/if_let.rs +++ b/examples/flow_control/if_let/if_let.rs @@ -1,11 +1,11 @@ fn main() { // All have type `Option` - let number = Some(7); + let number = Some(7); let letter: Option = None; let emoticon: Option = None; // The `if let` construct reads: "if `let` destructures `number` into - // `Some(i)`, evaluate the block (`{}`). Else do nothing. + // `Some(i)`, evaluate the block (`{}`). if let Some(i) = number { println!("Matched {:?}!", i); } @@ -14,7 +14,7 @@ fn main() { if let Some(i) = letter { println!("Matched {:?}!", i); } else { - // Destructure failed. Change the failure case. + // Destructure failed. Change to the failure case. println!("Didn't match a number. Let's go with a letter!"); }; @@ -23,12 +23,12 @@ fn main() { if let Some(i) = emoticon { println!("Matched {:?}!", i); - // Destructure failed. Evaluated the condition to see if this branch - // should be taken. + // Destructure failed. Evaluate an `else if` condition to see if the + // alternate failure branch should be taken: } else if i_like_letters { println!("Didn't match a number. Let's go with a letter!"); - // The condition evaluated false. This branch is the default. } else { + // The condition evaluated false. This branch is the default: println!("I don't like letters. Let's go with an emoticon :)!"); }; } From 0697110bd385ecab063d2fb2f7046a0cd61e34c1 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 13:51:05 -0800 Subject: [PATCH 0374/1122] Minor clarifications to while_let example --- examples/flow_control/while_let/input.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/flow_control/while_let/input.md b/examples/flow_control/while_let/input.md index 01cfe6cc3f..b3b6fe306a 100644 --- a/examples/flow_control/while_let/input.md +++ b/examples/flow_control/while_let/input.md @@ -1,5 +1,5 @@ Similar to `if let`, `while let` can make awkward `match` sequences -more tolerable. Consider, for example the following sequence: +more tolerable. Consider the following sequence that increments `i`: ```rust // Make `optional` of type `Option` @@ -19,14 +19,14 @@ loop { } // ^ Requires 3 indentations! }, - // Quit when the destructure fails, meaning `break`. + // Quit the loop when the destructure fails: _ => { break; } - // ^ Why should this be required? Seems superfluous. + // ^ Why should this be required? There must be a better way! } } ``` -`while let` makes this sequence much nicer: +Using `while let` makes this sequence much nicer: {while_let.play} From 8f6e2e8ec983dd46be9fe960fe057a347ebc6485 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 13:51:25 -0800 Subject: [PATCH 0375/1122] Grammar and minor clarifications to methods example --- examples/fn/methods/methods.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fn/methods/methods.rs b/examples/fn/methods/methods.rs index 26c803a663..91efad1782 100644 --- a/examples/fn/methods/methods.rs +++ b/examples/fn/methods/methods.rs @@ -12,7 +12,7 @@ impl Point { Point { x: 0.0, y: 0.0 } } - // Another static method, that takes two arguments + // Another static method, taking two arguments: fn new(x: f64, y: f64) -> Point { Point { x: x, y: y } } @@ -78,7 +78,7 @@ fn main() { p2: Point::new(3.0, 4.0), }; - // Instance method are called using the dot operator + // Instance methods are called using the dot operator // Note that the first argument `&self` is implicitly passed, i.e. // `rectangle.perimeter()` === `perimeter(&rectangle)` println!("Rectangle perimeter: {}", rectangle.perimeter()); @@ -94,7 +94,7 @@ fn main() { //rectangle.translate(1.0, 0.0); // TODO ^ Try uncommenting this line - // Ok, mutable object can call mutable methods + // Okay! Mutable objects can call mutable methods square.translate(1.0, 1.0); let pair = Pair(Box::new(1), Box::new(2)); From 466e2548702c02c6a498ae76e2418b8f5b756716 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 13:59:25 -0800 Subject: [PATCH 0376/1122] Readability update to capture example --- examples/fn/closures/capture/capture.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/fn/closures/capture/capture.rs b/examples/fn/closures/capture/capture.rs index a6cfbb6b7a..6cb5d86ae7 100644 --- a/examples/fn/closures/capture/capture.rs +++ b/examples/fn/closures/capture/capture.rs @@ -1,4 +1,6 @@ fn main() { + use std::mem; + let color = "green"; // A closure to print `color` which immediately borrows (`&`) @@ -36,13 +38,13 @@ fn main() { // A non-copy type. let movable = Box::new(3); - // `drop` requires `T` so this must take by value. A copy type + // `mem::drop` requires `T` so this must take by value. A copy type // would copy into the closure leaving the original untouched. // A non-copy must move and so `movable` immediately moves into // the closure. let consume = || { println!("`movable`: {:?}", movable); - drop(movable); + mem::drop(movable); }; // `consume` consumes the variable so this can only be called once. From 3e6b0213b2479584f3f72778ecd0e0a738aa271f Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 14:10:20 -0800 Subject: [PATCH 0377/1122] Minor formatting to print debug .md --- examples/hello/print/print_debug/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/print_debug/input.md b/examples/hello/print/print_debug/input.md index 876dfafc6f..9816fc2bc1 100644 --- a/examples/hello/print/print_debug/input.md +++ b/examples/hello/print/print_debug/input.md @@ -18,7 +18,7 @@ struct UnPrintable(i32); struct DebugPrintable(i32); ``` -All std library types automatically are printable with `{:?}` too: +All `std` library types automatically are printable with `{:?}` too: {debug.play} From d9627c639db42b934a3b1c61b0e242f3e8480702 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 17 Dec 2015 14:11:02 -0800 Subject: [PATCH 0378/1122] Consistency/readability on generic trait page --- examples/generics/gen_trait/input.md | 8 ++++---- examples/generics/gen_trait/trait.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/generics/gen_trait/input.md b/examples/generics/gen_trait/input.md index d77dee3135..67623a2e83 100644 --- a/examples/generics/gen_trait/input.md +++ b/examples/generics/gen_trait/input.md @@ -1,12 +1,12 @@ -Of course `trait`s can also be generic. Here is a trait which reimplements -the `Drop` `trait` as a generic method which `drop`s itself and an input. +Of course `trait`s can also be generic. Here we define one which reimplements +the `Drop` `trait` as a generic method to `drop` itself and an input. {trait.play} ### See also: -[`Drop`][drop], [`struct`s][structs], and [`trait`s][traits] +[`Drop`][Drop], [`struct`][structs], and [`trait`][traits] -[drop]: http://doc.rust-lang.org/std/ops/trait.Drop.html +[Drop]: http://doc.rust-lang.org/std/ops/trait.Drop.html [structs]: /custom_types/structs.html [traits]: /trait.html diff --git a/examples/generics/gen_trait/trait.rs b/examples/generics/gen_trait/trait.rs index 7f154bc072..d48d35c1b2 100644 --- a/examples/generics/gen_trait/trait.rs +++ b/examples/generics/gen_trait/trait.rs @@ -5,7 +5,7 @@ struct Null; // A trait generic over `T`. trait DoubleDrop { // It defines a method on the caller type which takes an - // additional single parameter and does nothing with it. + // additional single parameter `T` and does nothing with it. fn double_drop(self, _: T); } From 6e58f1c638a35d39d6674e682f49b8be1c5cbaf0 Mon Sep 17 00:00:00 2001 From: Seeker14491 Date: Mon, 21 Dec 2015 16:02:35 -0600 Subject: [PATCH 0379/1122] generics/assoc_items: Improve variable names --- .../generics/assoc_items/the_problem/problem.rs | 14 +++++++------- examples/generics/assoc_items/types/types.rs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/generics/assoc_items/the_problem/problem.rs b/examples/generics/assoc_items/the_problem/problem.rs index 09a25bd04d..129fe790fe 100644 --- a/examples/generics/assoc_items/the_problem/problem.rs +++ b/examples/generics/assoc_items/the_problem/problem.rs @@ -10,8 +10,8 @@ trait Contains { impl Contains for Container { // True if the numbers stored are equal. - fn contains(&self, number: &i32, digit: &i32) -> bool { - (&self.0 == number) && (&self.1 == digit) + fn contains(&self, number_1: &i32, number_2: &i32) -> bool { + (&self.0 == number_1) && (&self.1 == number_2) } // Grab the first number. @@ -29,14 +29,14 @@ fn difference(container: &C) -> i32 where } fn main() { - let number = 3; - let digit = 10; + let number_1 = 3; + let number_2 = 10; - let container = Container(number, digit); + let container = Container(number_1, number_2); println!("Does container contain {} and {}: {}", - &number, &digit, - container.contains(&number, &digit)); + &number_1, &number_2, + container.contains(&number_1, &number_2)); println!("First number: {}", container.first()); println!("Last number: {}", container.last()); diff --git a/examples/generics/assoc_items/types/types.rs b/examples/generics/assoc_items/types/types.rs index 85bc7a25e5..ec0379cf35 100644 --- a/examples/generics/assoc_items/types/types.rs +++ b/examples/generics/assoc_items/types/types.rs @@ -20,8 +20,8 @@ impl Contains for Container { type B = i32; // `&Self::A` and `&self::B` are also valid here. - fn contains(&self, number: &i32, digit: &i32) -> bool { - (&self.0 == number) && (&self.1 == digit) + fn contains(&self, number_1: &i32, number_2: &i32) -> bool { + (&self.0 == number_1) && (&self.1 == number_2) } // Grab the first number. fn first(&self) -> i32 { self.0 } @@ -35,14 +35,14 @@ fn difference(container: &C) -> i32 { } fn main() { - let number = 3; - let digit = 10; + let number_1 = 3; + let number_2 = 10; - let container = Container(number, digit); + let container = Container(number_1, number_2); println!("Does container contain {} and {}: {}", - &number, &digit, - container.contains(&number, &digit)); + &number_1, &number_2, + container.contains(&number_1, &number_2)); println!("First number: {}", container.first()); println!("Last number: {}", container.last()); From db805b8e1ea6f6cac701146d71cdf00bd1b4d045 Mon Sep 17 00:00:00 2001 From: Jay Oster Date: Mon, 28 Dec 2015 23:53:38 -0800 Subject: [PATCH 0380/1122] Fix whitespace in playpen result --- node_modules/gitbook-plugin-rust-playpen/book/editor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_modules/gitbook-plugin-rust-playpen/book/editor.css b/node_modules/gitbook-plugin-rust-playpen/book/editor.css index 543deae95d..697a913ca5 100644 --- a/node_modules/gitbook-plugin-rust-playpen/book/editor.css +++ b/node_modules/gitbook-plugin-rust-playpen/book/editor.css @@ -28,7 +28,7 @@ display: none; border-radius: 4px; font-family: Menlo, Monaco, Consolas, monospace; - white-space: normal; + white-space: pre-wrap; } #reset-code { From 5b3ff79a8c23c9a439d36c09e33234ad5e692367 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 30 Dec 2015 13:53:28 -0800 Subject: [PATCH 0381/1122] Ch8 Readability/grammar changes to text and examples --- examples/fn/closures/anonymity/anonymity.rs | 3 +-- examples/fn/closures/anonymity/input.md | 2 +- .../fn/closures/closure_analysis/input.md | 2 +- .../closure_analysis/iter_any/input.md | 2 +- .../closure_analysis/iter_any/iter_any.rs | 8 ++++---- .../closure_analysis/iter_find/input.md | 2 +- .../closure_analysis/iter_find/iter_find.rs | 7 ++++--- examples/fn/closures/input_functions/input.md | 10 +++++----- .../input_functions/input_functions.rs | 10 ++++++++-- .../fn/closures/input_parameters/input.md | 6 +++--- .../input_parameters/input_parameters.rs | 8 +++++--- .../fn/closures/output_parameters/input.md | 19 ++++++++++--------- examples/fn/hof/hof.rs | 10 +++++----- 13 files changed, 49 insertions(+), 40 deletions(-) diff --git a/examples/fn/closures/anonymity/anonymity.rs b/examples/fn/closures/anonymity/anonymity.rs index c09e260468..38f1bb841e 100644 --- a/examples/fn/closures/anonymity/anonymity.rs +++ b/examples/fn/closures/anonymity/anonymity.rs @@ -1,9 +1,8 @@ // `F` must implement `Fn` for a closure which takes no -// inputs and returns nothing. Exactly what is required +// inputs and returns nothing - exactly what is required // for `print`. fn apply(f: F) where F: Fn() { - f() } diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index c1a9f0b2c6..8f91c777d6 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -17,7 +17,7 @@ implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or is stored until calling. Since this new type is of unknown type, any usage in a function will require -generics. However, an unbounded type parameter (``) would still be ambiguous +generics. However, an unbounded type parameter `` would still be ambiguous and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or `FnOnce` (which it implements) is sufficient to specify its type. diff --git a/examples/fn/closures/closure_analysis/input.md b/examples/fn/closures/closure_analysis/input.md index 90e12b7ae9..ee3e8e9676 100644 --- a/examples/fn/closures/closure_analysis/input.md +++ b/examples/fn/closures/closure_analysis/input.md @@ -1 +1 @@ -A brief analysis of a few different `std` library closure examples. +This section contains a few examples of using closures in the `std` library. \ No newline at end of file diff --git a/examples/fn/closures/closure_analysis/iter_any/input.md b/examples/fn/closures/closure_analysis/iter_any/input.md index 5784888d68..d33e2fd867 100644 --- a/examples/fn/closures/closure_analysis/iter_any/input.md +++ b/examples/fn/closures/closure_analysis/iter_any/input.md @@ -21,6 +21,6 @@ pub trait Iterator { ### See also: -[`Iterator::any`][any] +[`std::iter::iterator::any`][any] [any]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/examples/fn/closures/closure_analysis/iter_any/iter_any.rs b/examples/fn/closures/closure_analysis/iter_any/iter_any.rs index 349ab12f1f..4df37c5700 100644 --- a/examples/fn/closures/closure_analysis/iter_any/iter_any.rs +++ b/examples/fn/closures/closure_analysis/iter_any/iter_any.rs @@ -2,16 +2,16 @@ fn main() { let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; - // `iter` yields `&i32`. Destructure to `i32`. + // `iter()` for vecs yields `&i32`. Destructure to `i32`. println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); - // `into_iter` yields `i32`. No destructuring required. + // `into_iter()` for vecs yields `i32`. No destructuring required. println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2)); let array1 = [1, 2, 3]; let array2 = [4, 5, 6]; - // `iter()` is normal. `into_iter()` for arrays unusually - // yields `&i32`. These would not normally both be `&`. + // `iter()` for arrays yields `&i32`. println!("2 in array1: {}", array1.iter() .any(|&x| x == 2)); + // `into_iter()` for arrays unusually yields `&i32`. println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2)); } diff --git a/examples/fn/closures/closure_analysis/iter_find/input.md b/examples/fn/closures/closure_analysis/iter_find/input.md index b965742ca5..8a08910499 100644 --- a/examples/fn/closures/closure_analysis/iter_find/input.md +++ b/examples/fn/closures/closure_analysis/iter_find/input.md @@ -21,6 +21,6 @@ pub trait Iterator { ### See also: -[`Iterator::find`][find] +[`std::iter::iterator::find`][find] [find]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/examples/fn/closures/closure_analysis/iter_find/iter_find.rs b/examples/fn/closures/closure_analysis/iter_find/iter_find.rs index 01b0c605bd..854da02530 100644 --- a/examples/fn/closures/closure_analysis/iter_find/iter_find.rs +++ b/examples/fn/closures/closure_analysis/iter_find/iter_find.rs @@ -2,8 +2,9 @@ fn main() { let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; - // `iter()` yields `&i32`. `into_iter()` yields `i32`. + // `iter()` for vecs yields `&i32`. let mut iter = vec1.iter(); + // `into_iter()` for vecs yields `i32`. let mut into_iter = vec2.into_iter(); // A reference to what is yielded is `&&i32`. Destructure to `i32`. @@ -14,9 +15,9 @@ fn main() { let array1 = [1, 2, 3]; let array2 = [4, 5, 6]; - // `iter()` is normal. `into_iter()` for arrays unusually - // yields `&i32`. These would not normally both be `&&`. + // `iter()` for arrays yields `&i32` println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2)); + // `into_iter()` for arrays unusually yields `&i32` println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2)); } diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md index e0aa3c2218..f63804e3ec 100644 --- a/examples/fn/closures/input_functions/input.md +++ b/examples/fn/closures/input_functions/input.md @@ -1,9 +1,9 @@ Since closures are possible as arguments, you might wonder if functions -are also possible and indeed they are. The previously mentioned `Fn`, -`FnMut`, and `FnOnce` `traits` all dictate what fashion a closure captures -variables from the enclosing scope. A function can *never* capture variables -and thus is strictly less flexible. Therefore, any function which can -take a closure as an argument can also take a function. +are possible as well. Indeed they are! The previously mentioned `Fn`, +`FnMut`, and `FnOnce` `traits` all dictate in what fashion a closure captures +variables from the enclosing scope. Because a function can *never* capture +variables, closures are strictly more flexible. Therefore, any function which +can take a closure as an argument can also take a function. {input_functions.play} diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs index 2392d1950d..b99199f440 100644 --- a/examples/fn/closures/input_functions/input_functions.rs +++ b/examples/fn/closures/input_functions/input_functions.rs @@ -1,9 +1,15 @@ +// A function which takes a closure as an argument and calls it. fn call_function(f: F) { f() } -fn print() { println!("I'm a function!") } +fn print() { + println!("I'm a function! I can be used like a closure.") +} fn main() { + let closure = || println!("I'm a closure!"); + call_function(closure); + call_function(print); -} +} \ No newline at end of file diff --git a/examples/fn/closures/input_parameters/input.md b/examples/fn/closures/input_parameters/input.md index 868d96ac35..32e3f43a54 100644 --- a/examples/fn/closures/input_parameters/input.md +++ b/examples/fn/closures/input_parameters/input.md @@ -1,12 +1,12 @@ -It has been noted that Rust chooses how to capture variable on the fly +It has been noted that Rust chooses how to capture variables on the fly without annotation. This is all very convenient in normal usage however when writing functions, this ambiguity is not allowed. The closure's complete -type including which capturing type must be annotated. The manner of capture +type, including which capturing type, must be annotated. The manner of capture a closure uses is annotated as one of the following `traits`: * `Fn`: takes captures by reference (`&T`) * `FnMut`: takes captures by mutable reference (`&mut T`) -* `FnOnce`: take captures by value (`T`) +* `FnOnce`: takes captures by value (`T`) Even annotated, these are very flexible: a parameter of `FnOnce` specifies the closure *may* capture by `T` or `&mut T` or `&T` at will (if a move is diff --git a/examples/fn/closures/input_parameters/input_parameters.rs b/examples/fn/closures/input_parameters/input_parameters.rs index 339f49d6a2..1ad6017051 100644 --- a/examples/fn/closures/input_parameters/input_parameters.rs +++ b/examples/fn/closures/input_parameters/input_parameters.rs @@ -1,6 +1,6 @@ -// A function which takes a closure as an argument and calls -// it. The closure takes no input and returns nothing. +// A function which takes a closure as an argument and calls it. fn apply(f: F) where + // The closure takes no input and returns nothing. F: FnOnce() { // ^ TODO: Try changing this to `Fn` or `FnMut`. @@ -16,6 +16,8 @@ fn apply_to_3(f: F) -> i32 where } fn main() { + use std::mem; + let greeting = "hello"; // A non-copy type. let mut farewell = "goodbye".to_owned(); @@ -34,7 +36,7 @@ fn main() { // Manually calling drop forces `farewell` to // be captured by value. Now requires `FnOnce`. - drop(farewell); + mem::drop(farewell); }; // Call the function which applies the closure. diff --git a/examples/fn/closures/output_parameters/input.md b/examples/fn/closures/output_parameters/input.md index b8489ffe04..200adb49c7 100644 --- a/examples/fn/closures/output_parameters/input.md +++ b/examples/fn/closures/output_parameters/input.md @@ -1,20 +1,21 @@ -Closures as input parameters are possible so returning one should also be -possible. However, returning closure types are problematic because Rust -currently only supports returning concrete (non-generic) types. Anonymous -closure types are, by definition, unknown and so returning a closure is only -possible by making it concrete. This can be done via boxing. +Using closures as input parameters are possible, so returning closures as +output parameters should also be possible. However, returning closure types +are problematic because Rust currently only supports returning concrete +(non-generic) types. Anonymous closure types are, by definition, unknown +and so returning a closure is only possible by making it concrete. This +can be done via boxing. -The valid types for returns are slightly different than before: +The valid traits for returns are slightly different than before: * `Fn`: normal * `FnMut`: normal -* `FnOnce`: There is some unsual things at play here, so the [`FnBox`][fnbox] +* `FnOnce`: There are some unusual things at play here, so the [`FnBox`][fnbox] type is currently needed, and is unstable. This is expected to change in the future. -Beyond this, the `move` keyword must be used which signals that all captures +Beyond this, the `move` keyword must be used, which signals that all captures occur by value. This is required because any captures by reference would be -dropped as soon as the function exited leaving invalid references in the +dropped as soon as the function exited, leaving invalid references in the closure. {output_parameters.play} diff --git a/examples/fn/hof/hof.rs b/examples/fn/hof/hof.rs index a0ce5aaf58..44f2079515 100644 --- a/examples/fn/hof/hof.rs +++ b/examples/fn/hof/hof.rs @@ -1,3 +1,7 @@ +fn is_odd(n: u32) -> bool { + n % 2 == 1 +} + fn main() { println!("Find the sum of all the squared odd numbers under 1000"); let upper = 1000; @@ -27,8 +31,4 @@ fn main() { .filter(|n| is_odd(*n)) // That are odd .fold(0, |sum, i| sum + i); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); -} - -fn is_odd(n: u32) -> bool { - n % 2 == 1 -} +} \ No newline at end of file From 597426ca9d3672214e35054fbc5f99ba39508bda Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 30 Dec 2015 13:58:15 -0800 Subject: [PATCH 0382/1122] Closure analysis changed to Closure examples Title from "Analysis" to "Examples in `std`" --- .../fn/closures/{closure_analysis => closure_examples}/input.md | 0 .../{closure_analysis => closure_examples}/iter_any/input.md | 0 .../{closure_analysis => closure_examples}/iter_any/iter_any.rs | 0 .../{closure_analysis => closure_examples}/iter_find/input.md | 0 .../iter_find/iter_find.rs | 0 examples/structure.json | 2 +- 6 files changed, 1 insertion(+), 1 deletion(-) rename examples/fn/closures/{closure_analysis => closure_examples}/input.md (100%) rename examples/fn/closures/{closure_analysis => closure_examples}/iter_any/input.md (100%) rename examples/fn/closures/{closure_analysis => closure_examples}/iter_any/iter_any.rs (100%) rename examples/fn/closures/{closure_analysis => closure_examples}/iter_find/input.md (100%) rename examples/fn/closures/{closure_analysis => closure_examples}/iter_find/iter_find.rs (100%) diff --git a/examples/fn/closures/closure_analysis/input.md b/examples/fn/closures/closure_examples/input.md similarity index 100% rename from examples/fn/closures/closure_analysis/input.md rename to examples/fn/closures/closure_examples/input.md diff --git a/examples/fn/closures/closure_analysis/iter_any/input.md b/examples/fn/closures/closure_examples/iter_any/input.md similarity index 100% rename from examples/fn/closures/closure_analysis/iter_any/input.md rename to examples/fn/closures/closure_examples/iter_any/input.md diff --git a/examples/fn/closures/closure_analysis/iter_any/iter_any.rs b/examples/fn/closures/closure_examples/iter_any/iter_any.rs similarity index 100% rename from examples/fn/closures/closure_analysis/iter_any/iter_any.rs rename to examples/fn/closures/closure_examples/iter_any/iter_any.rs diff --git a/examples/fn/closures/closure_analysis/iter_find/input.md b/examples/fn/closures/closure_examples/iter_find/input.md similarity index 100% rename from examples/fn/closures/closure_analysis/iter_find/input.md rename to examples/fn/closures/closure_examples/iter_find/input.md diff --git a/examples/fn/closures/closure_analysis/iter_find/iter_find.rs b/examples/fn/closures/closure_examples/iter_find/iter_find.rs similarity index 100% rename from examples/fn/closures/closure_analysis/iter_find/iter_find.rs rename to examples/fn/closures/closure_examples/iter_find/iter_find.rs diff --git a/examples/structure.json b/examples/structure.json index 33ac2d98b4..21cd7442e9 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -62,7 +62,7 @@ { "id": "anonymity", "title": "Type anonymity", "children": null }, { "id": "input_functions", "title": "Input functions", "children": null }, { "id": "output_parameters", "title": "As output parameters", "children": null }, - { "id": "closure_analysis", "title": "Analysis", "children": [ + { "id": "closure_examples", "title": "Examples in `std`", "children": [ { "id": "iter_any", "title": "Iterator::any", "children": null }, { "id": "iter_find", "title": "Iterator::find", "children": null } ] } From 8a9ce18afec5ed716a3696fa575f0bb0941013de Mon Sep 17 00:00:00 2001 From: Jonathan L Date: Wed, 30 Dec 2015 14:39:28 -0800 Subject: [PATCH 0383/1122] Added link to precedence list of Rust reference #98 --- examples/primitives/literals/input.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/primitives/literals/input.md b/examples/primitives/literals/input.md index 2c027333c4..d037ccc6fe 100644 --- a/examples/primitives/literals/input.md +++ b/examples/primitives/literals/input.md @@ -11,9 +11,10 @@ We need to tell the compiler the type of the literals we use. For now, we'll use the `u32` suffix to indicate that the literal is an unsigned 32-bit integer, and the `i32` suffix to indicate that it's a signed 32-bit integer. -The operators available and their precedence are similar to other +The operators available and their precedence [in Rust][rust op-prec] are similar to other [C-like languages][op-prec]. {literals.play} +[rust op-prec]: http://doc.rust-lang.org/reference.html#operator-precedence [op-prec]: https://en.wikipedia.org/wiki/Operator_precedence#Programming_languages From 472e91a344a34d8c8209ad5b743d69666fdb25ba Mon Sep 17 00:00:00 2001 From: Stefan Scherfke Date: Fri, 1 Jan 2016 14:08:53 +0100 Subject: [PATCH 0384/1122] Fixed typo in section 1.2 print --- examples/hello/print/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/print/input.md b/examples/hello/print/input.md index db01c6fc56..e83d5d9259 100644 --- a/examples/hello/print/input.md +++ b/examples/hello/print/input.md @@ -22,7 +22,7 @@ for these types. To print text for custom types, more steps are required. ### Activities - * Fix the two isses in the above code (see FIXME) so that it runs without + * Fix the two issues in the above code (see FIXME) so that it runs without error. * Add a `println!` macro that prints: `Pi is roughly 3.143`, using twenty-two divided by seven to generate the estimate for Pi. (Hint: you may need to From ed37d5f00c1367ebcf94f0bfa9579b3290b7e294 Mon Sep 17 00:00:00 2001 From: Clemens Tolboom Date: Mon, 4 Jan 2016 08:27:56 +0100 Subject: [PATCH 0385/1122] Better? wording for unwrap As a novice it took some time to get it. Splitting the comment makes it easier to me. What do you think? --- examples/std/option/option.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/std/option/option.rs b/examples/std/option/option.rs index 176055cf72..e2cc8aec9d 100644 --- a/examples/std/option/option.rs +++ b/examples/std/option/option.rs @@ -30,8 +30,9 @@ fn main() { let optional_float = Some(0f32); - // The `unwrap` method will extract the value wrapped in a `Some` variant, - // or will `panic!` if called on a `None` variant + // Unwrapping a `Some` variant will extract the value wrapped. println!("{:?} unwraps to {:?}", optional_float, optional_float.unwrap()); + + // Unwrapping a `None` variant will `panic!` println!("{:?} unwraps to {:?}", none, none.unwrap()); } From 65f5bbb6cbf5e4744367af950b0d06cc828f3df7 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 4 Jan 2016 11:32:39 -0800 Subject: [PATCH 0386/1122] Updates to Chapter 9 Readability/grammar, renamed DRY for clarity, and changed a macro name for clarity --- examples/macros/designators/designators.rs | 17 ++++++++++------- examples/macros/dry/dry.rs | 6 +++--- examples/macros/dry/input.md | 4 ++-- examples/macros/overload/input.md | 3 ++- examples/macros/overload/overload.rs | 9 +++++---- examples/macros/repeat/repeat.rs | 16 ++++++++-------- examples/macros/simple.rs | 8 ++++---- examples/structure.json | 2 +- 8 files changed, 35 insertions(+), 30 deletions(-) diff --git a/examples/macros/designators/designators.rs b/examples/macros/designators/designators.rs index b6dd511b9e..cba11c8a80 100644 --- a/examples/macros/designators/designators.rs +++ b/examples/macros/designators/designators.rs @@ -1,23 +1,26 @@ macro_rules! create_function { - // this macro takes an argument of "type" `ident` - // the `ident` designator is used for variable/function names + // This macro takes an argument of type `ident` and creates + // a function named `$func_name`. + // The `ident` designator is used for variable/function names. ($func_name:ident) => ( - // this macro creates a function with name `$func_name` fn $func_name() { - // the stringify! macro converts an `ident` into a string + // The `stringify!` macro converts an `ident` into a string. println!("You called {:?}()", stringify!($func_name)) } ) } +// Create functions named `foo` and `bar` with the above macro. create_function!(foo); create_function!(bar); macro_rules! print_result { - // the `expr` designator is used for expressions + // This macro takes an expression of type `expr` and prints + // it as a string along with its result. + // The `expr` designator is used for expressions. ($expression:expr) => ( - // stringify! will convert the expression *as it is* into a string + // `stringify!` will convert the expression *as it is* into a string. println!("{:?} = {:?}", stringify!($expression), $expression) @@ -30,7 +33,7 @@ fn main() { print_result!(1u32 + 1); - // remember that blocks are expressions + // Recall that blocks are expressions too! print_result!({ let x = 1u32; diff --git a/examples/macros/dry/dry.rs b/examples/macros/dry/dry.rs index fad24061fb..111bb4e237 100644 --- a/examples/macros/dry/dry.rs +++ b/examples/macros/dry/dry.rs @@ -2,7 +2,7 @@ use std::ops::{Add, Mul, Sub}; macro_rules! assert_equal_len { // The `tt` (token tree) designator is used for - // operators and tokens + // operators and tokens. ($a:ident, $b: ident, $func:ident, $op:tt) => ( assert!($a.len() == $b.len(), "{:?}: dimension mismatch: {:?} {:?} {:?}", @@ -26,7 +26,7 @@ macro_rules! op { ) } -// implement add_assign, mul_assign, and sub_assign functions +// Implement `add_assign`, `mul_assign`, and `sub_assign` functions. op!(add_assign, Add, +=, add); op!(mul_assign, Mul, *=, mul); op!(sub_assign, Sub, -=, sub); @@ -50,7 +50,7 @@ mod test { } } - // test add_assign, mul_assign and sub_assign + // Test `add_assign`, `mul_assign` and `sub_assign` test!(add_assign, 1u32, 2u32, 3u32); test!(mul_assign, 2u32, 3u32, 6u32); test!(sub_assign, 3u32, 2u32, 1u32); diff --git a/examples/macros/dry/input.md b/examples/macros/dry/input.md index 3ee64e9710..32391a5571 100644 --- a/examples/macros/dry/input.md +++ b/examples/macros/dry/input.md @@ -1,6 +1,6 @@ -Macros allow writing DRY code, by factoring out the common parts of functions +Macros allow writing DRY code by factoring out the common parts of functions and/or test suites. Here is an example that implements and tests the `+=`, `*=` -and `-=` operators on `Vec`. +and `-=` operators on `Vec`: {dry.rs} diff --git a/examples/macros/overload/input.md b/examples/macros/overload/input.md index 940c2c122b..2d166ce32a 100644 --- a/examples/macros/overload/input.md +++ b/examples/macros/overload/input.md @@ -1,3 +1,4 @@ -Macros can be overloaded to accept different combinations of arguments. +Macros can be overloaded to accept different combinations of arguments. +In that regard, `macro_rules!` can work similarly to a match block: {overload.play} diff --git a/examples/macros/overload/overload.rs b/examples/macros/overload/overload.rs index 12392b1e8f..389df55536 100644 --- a/examples/macros/overload/overload.rs +++ b/examples/macros/overload/overload.rs @@ -1,14 +1,15 @@ -// macro_rules! is similar to a match block +// `test!` will compare `$left` and `$right` +// in different ways depending on how you invoke it: macro_rules! test { - // the arguments don't need to be separated by a comma - // any template can be used + // Arguments don't need to be separated by a comma. + // Any template can be used! ($left:expr; and $right:expr) => ( println!("{:?} and {:?} is {:?}", stringify!($left), stringify!($right), $left && $right) ); - // ^ each arm must be ended with a semicolon + // ^ each arm must end with a semicolon. ($left:expr; or $right:expr) => ( println!("{:?} or {:?} is {:?}", stringify!($left), diff --git a/examples/macros/repeat/repeat.rs b/examples/macros/repeat/repeat.rs index 2611b75403..e25aad8d29 100644 --- a/examples/macros/repeat/repeat.rs +++ b/examples/macros/repeat/repeat.rs @@ -1,16 +1,16 @@ -// min! will calculate the minimum of any number of arguments -macro_rules! min { - // base case +// `min!` will calculate the minimum of any number of arguments. +macro_rules! find_min { + // Base case: ($x:expr) => ($x); // `$x` followed by at least one `$y,` ($x:expr, $($y:expr),+) => ( - // call min! on the tail `$y` - std::cmp::min($x, min!($($y),+)) + // Call `find_min!` on the tail `$y` + std::cmp::min($x, find_min!($($y),+)) ) } fn main() { - println!("{}", min!(1u32)); - println!("{}", min!(1u32 + 2 , 2u32)); - println!("{}", min!(5u32, 2u32 * 3, 4u32)); + println!("{}", find_min!(1u32)); + println!("{}", find_min!(1u32 + 2 , 2u32)); + println!("{}", find_min!(5u32, 2u32 * 3, 4u32)); } diff --git a/examples/macros/simple.rs b/examples/macros/simple.rs index 1f7b742d79..4268b6fef4 100644 --- a/examples/macros/simple.rs +++ b/examples/macros/simple.rs @@ -1,13 +1,13 @@ -// This is the simplest macro, `say_hello` is the name of the macro +// This is a simple macro named `say_hello`. macro_rules! say_hello { - // `()` indicates that the macro takes no argument + // `()` indicates that the macro takes no argument. () => ( - // the macro will expand into the contents of this block + // The macro will expand into the contents of this block. println!("Hello!"); ) } fn main() { - // this call will expand into `println!("Hello");` + // This call will expand into `println!("Hello");` say_hello!() } diff --git a/examples/structure.json b/examples/structure.json index 21cd7442e9..a64c90df6f 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -73,7 +73,7 @@ { "id": "designators", "title": "Designators", "children": null }, { "id": "overload", "title": "Overload", "children": null }, { "id": "repeat", "title": "Repeat", "children": null }, - { "id": "dry", "title": "DRY", "children": null } + { "id": "dry", "title": "DRY (Don't Repeat Yourself)", "children": null } ] }, { "id": "mod", "title": "Modules", "children": [ { "id": "visibility", "title": "Visibility", "children": null }, From d347b22cabd02156b4df402f372593411991a798 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 4 Jan 2016 11:47:48 -0800 Subject: [PATCH 0387/1122] type -> designator Clarification based on comment --- examples/macros/designators/designators.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/macros/designators/designators.rs b/examples/macros/designators/designators.rs index cba11c8a80..d85f9c7348 100644 --- a/examples/macros/designators/designators.rs +++ b/examples/macros/designators/designators.rs @@ -1,6 +1,6 @@ macro_rules! create_function { - // This macro takes an argument of type `ident` and creates - // a function named `$func_name`. + // This macro takes an argument of designator `ident` and + // creates a function named `$func_name`. // The `ident` designator is used for variable/function names. ($func_name:ident) => ( fn $func_name() { From 4bd72aeade46169cfaaf0a0450c5d895eed9dbb7 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 5 Jan 2016 14:04:23 -0800 Subject: [PATCH 0388/1122] Readability changes to Ch10, removed first example code Added "See also" to 10.2, reordered parts of example code, reduced nesting and unclear paths where helpful to new readers --- examples/mod/input.md | 2 - examples/mod/mod.rs | 28 ---------- examples/mod/struct_visibility/input.md | 15 +++-- examples/mod/struct_visibility/struct.rs | 16 +++--- examples/mod/super/input.md | 4 +- examples/mod/super/super.rs | 68 ++++++++++------------- examples/mod/use/use.rs | 12 ++-- examples/mod/visibility/visibility.rs | 70 +++++++++++------------- 8 files changed, 88 insertions(+), 127 deletions(-) delete mode 100644 examples/mod/mod.rs diff --git a/examples/mod/input.md b/examples/mod/input.md index ea270a2bf5..d9d42576f9 100644 --- a/examples/mod/input.md +++ b/examples/mod/input.md @@ -4,5 +4,3 @@ them. A module is a collection of items: functions, structs, traits, `impl` blocks, and even other modules. - -{mod.play} diff --git a/examples/mod/mod.rs b/examples/mod/mod.rs deleted file mode 100644 index b8d2b1ad4d..0000000000 --- a/examples/mod/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -fn function() { - println!("called `function()`"); -} - -// A module named `my` -mod my { - // A module can contain items like functions - #[allow(dead_code)] - fn function() { - println!("called `my::function()`"); - } - - // Modules can be nested - mod nested { - #[allow(dead_code)] - fn function() { - println!("called `my::nested::function()`"); - } - } -} - -fn main() { - function(); - - // Error! `my::function` is private - my::function(); - // TODO ^ Comment out this line -} diff --git a/examples/mod/struct_visibility/input.md b/examples/mod/struct_visibility/input.md index 7d4b11e647..fbd356cd4e 100644 --- a/examples/mod/struct_visibility/input.md +++ b/examples/mod/struct_visibility/input.md @@ -1,6 +1,13 @@ -Structs have an extra level of visibility, their fields can be public or -private (which is the default). This visibility only matters when a -struct is accessed from outside the module where it is defined, and its -goal is information hiding (encapsulation). +Structs have an extra level of visibility with their fields. The visibility +defaults to private, and can be overridden with the `pub` modifier. This +visibility only matters when a struct is accessed from outside the module +where it is defined, and has the goal of hiding information (encapsulation). {struct.play} + +### See also: + +[generics][generics] and [methods][methods] + +[generics]: /generics.html +[methods]: /fn/methods.html \ No newline at end of file diff --git a/examples/mod/struct_visibility/struct.rs b/examples/mod/struct_visibility/struct.rs index 581fe76de8..59bb171ed8 100644 --- a/examples/mod/struct_visibility/struct.rs +++ b/examples/mod/struct_visibility/struct.rs @@ -1,17 +1,17 @@ mod my { - // A public struct with public fields + // A public struct with a public field of generic type `T` pub struct WhiteBox { pub contents: T, } - // A public struct with private fields + // A public struct with a private field of generic type `T` #[allow(dead_code)] pub struct BlackBox { contents: T, } impl BlackBox { - // A public constructor + // A public constructor method pub fn new(contents: T) -> BlackBox { BlackBox { contents: contents, @@ -24,19 +24,19 @@ fn main() { // Public structs with public fields can be constructed as usual let white_box = my::WhiteBox { contents: "public information" }; - // and their fields can be normally accessed + // and their fields can be normally accessed. println!("The white box contains: {}", white_box.contents); - // but public structs with private fields can't be constructed + // Public structs with private fields cannot be constructed using field names. // Error! `BlackBox` has private fields //let black_box = my::BlackBox { contents: "classified information" }; // TODO ^ Try uncommenting this line - // However, structs with private fields can still be created using - // constructors + // However, structs with private fields can be created using + // public constructors let _black_box = my::BlackBox::new("classified information"); - // The private fields of a struct can't be accessed + // and the private fields of a public struct cannot be accessed. // Error! The `contents` field is private //println!("The black box contains: {}", _black_box.contents); // TODO ^ Try uncommenting this line diff --git a/examples/mod/super/input.md b/examples/mod/super/input.md index 05b1415fa3..966ed166fb 100644 --- a/examples/mod/super/input.md +++ b/examples/mod/super/input.md @@ -1,4 +1,4 @@ -The `super` and `self` keywords can be used in the path, to remove ambiguity -when accessing items. +The `super` and `self` keywords can be used in the path to remove ambiguity +when accessing items and to prevent unnecessary hardcoding of paths. {super.play} diff --git a/examples/mod/super/super.rs b/examples/mod/super/super.rs index 7f6a800659..b882abcec7 100644 --- a/examples/mod/super/super.rs +++ b/examples/mod/super/super.rs @@ -2,55 +2,45 @@ fn function() { println!("called `function()`"); } -mod my { - pub fn indirect_call() { - // Let's access all the functions named `function` from this scope - print!("called `my::indirect_call()`, that\n> "); - - // `my::function` can be called directly - function(); - - { - // This will bind to the `cool::function` in the *crate* scope - // In this case the crate scope is the outermost scope - use cool::function as root_cool_function; - - print!("> "); - root_cool_function(); - } - - { - // `self` refers to the current module scope, in this case: `my` - use self::cool::function as my_cool_function; - - print!("> "); - my_cool_function(); - } - - { - // `super` refers to the parent scope, i.e. outside of the `my` - // module - use super::function as root_function; - - print!("> "); - root_function(); - } +mod cool { + pub fn function() { + println!("called `cool::function()`"); } +} +mod my { fn function() { println!("called `my::function()`"); } - + mod cool { pub fn function() { println!("called `my::cool::function()`"); } } -} - -mod cool { - pub fn function() { - println!("called `cool::function()`"); + + pub fn indirect_call() { + // Let's access all the functions named `function` from this scope! + print!("called `my::indirect_call()`, that\n> "); + + // The `self` keyword refers to the current module scope - in this case `my`. + // Calling `self::function()` and calling `function()` directly both give + // the same result, because they refer to the same function. + self::function(); + function(); + + // We can also use `self` to access another module inside `my`: + self::cool::function(); + + // The `super` keyword refers to the parent scope (outside the `my` module). + super::function(); + + // This will bind to the `cool::function` in the *crate* scope. + // In this case the crate scope is the outermost scope. + { + use cool::function as root_function; + root_function(); + } } } diff --git a/examples/mod/use/use.rs b/examples/mod/use/use.rs index 3903739c5e..0f46965807 100644 --- a/examples/mod/use/use.rs +++ b/examples/mod/use/use.rs @@ -1,4 +1,4 @@ -// Bind the `deeply::nested::function` path to `other_function` +// Bind the `deeply::nested::function` path to `other_function`. use deeply::nested::function as other_function; fn function() { @@ -19,16 +19,14 @@ fn main() { println!("Entering block"); { - // This is equivalent to `use deeply::nested::function as function` - // This `function` will shadow the outer one + // This is equivalent to `use deeply::nested::function as function`. + // This `function()` will shadow the outer one. use deeply::nested::function; - function(); + // `use` bindings have a local scope. In this case, the + // shadowing of `function()` is only in this block. println!("Leaving block"); - - // `use` bindings have a local scope, in this case the `function` - // shadowing is only available in this scope } function(); diff --git a/examples/mod/visibility/visibility.rs b/examples/mod/visibility/visibility.rs index 8081b1b8d2..95e5927cfc 100644 --- a/examples/mod/visibility/visibility.rs +++ b/examples/mod/visibility/visibility.rs @@ -1,27 +1,23 @@ -fn function() { - println!("called `function()`"); -} - +// A module named `my` mod my { - // A public function - pub fn function() { - println!("called `my::function()`"); - } - - // A private function + // Items in modules default to private visibility. fn private_function() { println!("called `my::private_function()`"); } - - // Items can access other items in the same module + + // Use the `pub` modifier to override default visibility. + pub fn function() { + println!("called `my::function()`"); + } + + // Items can access other items in the same module, + // even when private. pub fn indirect_access() { print!("called `my::indirect_access()`, that\n> "); - - // regardless of their visibility private_function(); } - // A public module + // Modules can also be nested pub mod nested { pub fn function() { println!("called `my::nested::function()`"); @@ -32,42 +28,42 @@ mod my { println!("called `my::nested::private_function()`"); } } - - // A private module - mod inaccessible { + + // Nested modules follow the same rules for visibility + mod private_nested { #[allow(dead_code)] - pub fn public_function() { - println!("called `my::inaccessible::public_function()`"); + pub fn function() { + println!("called `my::private_nested::function()`"); } } } -fn main() { - // The public items of a module can be accessed - my::function(); +fn function() { + println!("called `function()`"); +} - // modules allow disambiguation between items that have the same name +fn main() { + // Modules allow disambiguation between items that have the same name. function(); + my::function(); + + // Public items, including those inside nested modules, can be + // accessed from outside the parent module. + my::indirect_access(); + my::nested::function(); - // The private items of a module can't be directly accessed + // Private items of a module cannot be directly accessed, even if + // nested in a public module: + // Error! `private_function` is private //my::private_function(); // TODO ^ Try uncommenting this line - my::indirect_access(); - - // Public items inside public nested modules can be accessed from outside - // the parent module - my::nested::function(); - - // but private items inside public nested modules can't be accessed // Error! `private_function` is private //my::nested::private_function(); // TODO ^ Try uncommenting this line - // Items inside private nested modules can't be accessed, regardless of - // their visibility - // Error! `inaccessible` is a private module - //my::inaccessible::public_function(); + // Error! `private_nested` is a private module + //my::private_nested::function(); // TODO ^ Try uncommenting this line -} +} \ No newline at end of file From db1424b1b994f28308d0f59adf2c1ea71bbe762d Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 6 Jan 2016 17:47:09 -0800 Subject: [PATCH 0389/1122] Renamed 12.1 to `dead_code` New name more accurately reflects content of page and improves searching. --- examples/structure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/structure.json b/examples/structure.json index 21cd7442e9..7fd996bc73 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -87,7 +87,7 @@ { "id": "link", "title": "`extern crate`", "children": null } ] }, { "id": "attribute", "title": "Attributes", "children": [ - { "id": "unused", "title": "Unused", "children": null }, + { "id": "unused", "title": "`dead_code`", "children": null }, { "id": "crate", "title": "Crates", "children": null }, { "id": "cfg", "title": "`cfg`", "children": [ { "id": "custom", "title": "Custom", "children": null } From 7719921aa8c7593e254e963e13568d9396167cf4 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 6 Jan 2016 17:49:05 -0800 Subject: [PATCH 0390/1122] Updates to 13. Generics Changed .md to be more consistent with use of the word "generic". Changed example code to use less confusing letters for concrete type/generic type. --- examples/attribute/cfg/input.md | 2 +- examples/generics/generics.rs | 35 +++++++++++++++++---------------- examples/generics/input.md | 27 ++++++++++++++++--------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/examples/attribute/cfg/input.md b/examples/attribute/cfg/input.md index 0bce172d22..3e7df7ba88 100644 --- a/examples/attribute/cfg/input.md +++ b/examples/attribute/cfg/input.md @@ -3,7 +3,7 @@ Conditional compilation is possible through two different operators: * the `cfg` attribute: `#[cfg(...)]` in attribute position * the `cfg!` macro: `cfg!(...)` in boolean expressions -Both utilize identical syntax. +Both utilize identical argument syntax. {cfg.play} diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index 2c1f632c24..adbde8684e 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -1,25 +1,26 @@ -// A concrete type `T`. -struct T; +// A concrete type `A`. +struct A; -// The first use of `T` was not preceded by `` so `Single` must -// be a concrete type. `T` is defined at the top. -struct Single(T); -// ^ Here is `Single`s first use of the type `T`. +// In defining the type `Single`, the first use of `A` is not preceded by ``. +// Therefore, `Single` is a concrete type, and `A` is defined as above. +struct Single(A); +// ^ Here is `Single`s first use of the type `A`. -// The first use of `T` is preceded by ``. `SingleGen` must be -// generic and has not yet been specialized. `T` could be anything -// including `T` at the top. +// Here, `` precedes the first use of `T`, so `SingleGen` is a generic type. +// Because the type parameter `T` is generic, it could be anything, including +// the concrete type `A` defined at the top. struct SingleGen(T); -// Instantiating the types can be implicit or explicit. fn main() { - // Regular `Single`. - let _s = Single(T); - - // `SingleGen` explicity specialized. + // `Single` is concrete and explicitly takes `A`. + let _s = Single(A); + + // Instantiating generic types can be explicit or implicit. + // `SingleGen` explicitly specialized: let _char: SingleGen = SingleGen('a'); - // `SingleGen`s implicitly specialized. - let _t = SingleGen(T); // Uses `T` at top. - let _i32 = SingleGen(6); // Uses `i32`. + // `SingleGen` implicitly specialized: + let _t = SingleGen(A); // Uses `A` defined at the top. + let _i32 = SingleGen(6); // Uses `i32`. + let _char = SingleGen('a'); // Uses `char`. } diff --git a/examples/generics/input.md b/examples/generics/input.md index bfd54d0471..fb893737ea 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -1,14 +1,22 @@ -Generics is the topic of generalizing types and functionality to be more broad -than one specific type. This is extremely useful in reducing code duplication -in many ways. We will find though that being generic will involve taking -great care to actually specify what types a generic type is actually valid -over. This will require a rather involving syntax, though it seems -straightforward at first. +Generics is the topic of generalizing types and functionality to broader +cases. This is extremely useful in reducing code duplication in many ways, +but requires a rather involving syntax. However, we will find that being +generic involves taking great care to specify over what types a generic type +is actually considered valid. -A type is specified as generic by ``. There are 2 basic rules -regarding this which are applied *at* the type's first use: +A type parameter is specified as generic by the use of angle brackets and +[camel case][camelcase]: ``. "Generic type parameters" are +typically represented as ``. In Rust, "generic" also describes anything that +accepts one or more generic type parameters ``. For example, defining a +*generic function* named `foo` that takes an argument `T` of any type: -* Any type previously and locally specified to be generic is generic. +```rust +fn foo(T) { ... } +``` + +There are 2 basic rules regarding this which are applied at the type's first use: + +* Any type previously specified to be generic is generic. * Everything else is concrete (non-generic). These rules play out like this: @@ -20,3 +28,4 @@ These rules play out like this: [`struct`s][structs] [structs]: /custom_types/structs.html +[camelcase]: https://en.wikipedia.org/wiki/CamelCase \ No newline at end of file From 00033d4b48009dafd2f9ae8210135384d265a1f5 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 8 Jan 2016 12:31:11 -0800 Subject: [PATCH 0391/1122] Clarifications on <> placing Explicitly called out the edge case and reworded some of the example to match --- examples/generics/generics.rs | 7 ++++--- examples/generics/input.md | 16 +++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index adbde8684e..7f1f945c3f 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -15,11 +15,12 @@ fn main() { // `Single` is concrete and explicitly takes `A`. let _s = Single(A); - // Instantiating generic types can be explicit or implicit. - // `SingleGen` explicitly specialized: + // Here, `SingleGen` is explicitly specialized. This reads as: + // Create a variable `_char` of type `SingleGen` + // and give it the value `SingleGen('a')` let _char: SingleGen = SingleGen('a'); - // `SingleGen` implicitly specialized: + // `SingleGen` can also be implicitly specialized: let _t = SingleGen(A); // Uses `A` defined at the top. let _i32 = SingleGen(6); // Uses `i32`. let _char = SingleGen('a'); // Uses `char`. diff --git a/examples/generics/input.md b/examples/generics/input.md index fb893737ea..15ac2795ae 100644 --- a/examples/generics/input.md +++ b/examples/generics/input.md @@ -7,19 +7,21 @@ is actually considered valid. A type parameter is specified as generic by the use of angle brackets and [camel case][camelcase]: ``. "Generic type parameters" are typically represented as ``. In Rust, "generic" also describes anything that -accepts one or more generic type parameters ``. For example, defining a -*generic function* named `foo` that takes an argument `T` of any type: +accepts one or more generic type parameters ``. Any type specified as a +generic type parameter is generic, and everything else is concrete (non-generic). + +For example, defining a *generic function* named `foo` that takes an argument +`T` of any type: ```rust fn foo(T) { ... } ``` -There are 2 basic rules regarding this which are applied at the type's first use: - -* Any type previously specified to be generic is generic. -* Everything else is concrete (non-generic). +Because `T` has been specified as a generic type parameter, it is considered +generic when used here as `(T)`. This is the case even if `T` has previously +been defined as a `struct`. -These rules play out like this: +This example shows some of the syntax in action: {generics.play} From 33d6fe64f0ccfa3e7692be8d75a4d11eac03efe8 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 14 Jan 2016 21:47:43 +0200 Subject: [PATCH 0392/1122] std::box: remove a lint that is not needed --- examples/std/box/box.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/std/box/box.rs b/examples/std/box/box.rs index eb81ba0639..6ca5354ec8 100644 --- a/examples/std/box/box.rs +++ b/examples/std/box/box.rs @@ -1,6 +1,5 @@ use std::mem; -#[allow(dead_code)] #[derive(Clone, Copy)] struct Point { x: f64, From f94da8f49b95ae72a652cad2a0a3085e4d06a9b9 Mon Sep 17 00:00:00 2001 From: "Prasanna V. Loganathar" Date: Wed, 20 Jan 2016 01:43:47 +0530 Subject: [PATCH 0393/1122] Update cast.rs --- examples/cast/cast.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/cast/cast.rs b/examples/cast/cast.rs index 4d5f44fb6e..ecb81e85d3 100644 --- a/examples/cast/cast.rs +++ b/examples/cast/cast.rs @@ -22,6 +22,7 @@ fn main() { println!("1000 as a u16 is: {}", 1000 as u16); // 1000 - 256 - 256 - 256 = 232 + // Basically, it just uses the 8 bits from the least significant bit, and truncates the MSB println!("1000 as a u8 is : {}", 1000 as u8); // -1 + 256 = 255 println!(" -1 as a u8 is : {}", (-1i8) as u8); From 796c6ce57581c282bbb805f683729e3b8ad89c5a Mon Sep 17 00:00:00 2001 From: "Prasanna V. Loganathar" Date: Wed, 20 Jan 2016 05:29:29 +0530 Subject: [PATCH 0394/1122] Update cast.rs --- examples/cast/cast.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/cast/cast.rs b/examples/cast/cast.rs index ecb81e85d3..59db9eede0 100644 --- a/examples/cast/cast.rs +++ b/examples/cast/cast.rs @@ -22,7 +22,8 @@ fn main() { println!("1000 as a u16 is: {}", 1000 as u16); // 1000 - 256 - 256 - 256 = 232 - // Basically, it just uses the 8 bits from the least significant bit, and truncates the MSB + // Under the hood, the first 8 bits from the least significant bit (LSB) are used, + // while the rest towards the most significant bit (MSB) get truncated. println!("1000 as a u8 is : {}", 1000 as u8); // -1 + 256 = 255 println!(" -1 as a u8 is : {}", (-1i8) as u8); From bfa4285b402a874d642740fcf0497ebd32c002be Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 20 Jan 2016 11:22:54 -0800 Subject: [PATCH 0395/1122] Removed 13.7.3 - Constraining Issue #700 --- .../assoc_items/constrain/constrain.rs | 37 ------------------- .../generics/assoc_items/constrain/input.md | 30 --------------- examples/structure.json | 1 - 3 files changed, 68 deletions(-) delete mode 100644 examples/generics/assoc_items/constrain/constrain.rs delete mode 100644 examples/generics/assoc_items/constrain/input.md diff --git a/examples/generics/assoc_items/constrain/constrain.rs b/examples/generics/assoc_items/constrain/constrain.rs deleted file mode 100644 index b855f698ea..0000000000 --- a/examples/generics/assoc_items/constrain/constrain.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::fmt::Display; - -struct Container(T); - -// Trait returns whatever is inside. -trait Contains { - type A; - // Return inner element. - fn inner(&self) -> Self::A; -} - -impl Contains for Container { - type A = T; - - // Clone to prevent move. - fn inner(&self) -> Self::A { self.0.clone() } -} - -// Bounds on associated types. -fn printer(c: C) where - C: Contains, - C::A: Display { - println!("{}", c.inner()); -} - -// The assignment shorthand: -fn num_small(c: C) -> i32 where - C: Contains { - c.inner() -} - - -fn main() { - printer(Container(17i32)); - - println!("{}", num_small(Container(4i32))); -} diff --git a/examples/generics/assoc_items/constrain/input.md b/examples/generics/assoc_items/constrain/input.md deleted file mode 100644 index a4f3065ff2..0000000000 --- a/examples/generics/assoc_items/constrain/input.md +++ /dev/null @@ -1,30 +0,0 @@ -Functionality depending on associated types may require applying bounds. - -```rust -trait Contains { - type A; - ... -} - -// Bounds are applied through the container: `C::A: Trait`. -fn apply_bounds(c: C) where - C: Contains, - C::A: Display { ... } - -// Caveat: This hasn't been implemented yet and doesn't work. -// -// Equality is also through the container: `C::A = type`. -fn apply_eq(c: C) where - C: Contains, - C::A = i32 { ... } - -// Note: There is no bounds shorthand. Only equality. -// -// An equality shorthand is provided: -fn apply_eq_shorthand(c: C) where - C: Contains { ... } -``` - -The full example: - -{constrain.play} diff --git a/examples/structure.json b/examples/structure.json index 8c44a076fa..234cb4a75f 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -105,7 +105,6 @@ { "id": "assoc_items", "title": "Associated items", "children": [ { "id": "the_problem", "title": "The problem", "children": null }, { "id": "types", "title": "Associated types", "children": null }, - { "id": "constrain", "title": "Constraining", "children": null }, { "id": "testcase_add", "title": "Testcase: Add", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ From 5391cbf559f6e7702d80f774becf98f2175ff981 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 20 Jan 2016 11:24:14 -0800 Subject: [PATCH 0396/1122] Removed 13.7.4 Testcase:Add Issue #701 --- .../assoc_items/testcase_add/input.md | 4 -- .../assoc_items/testcase_add/testcase.rs | 51 ------------------- examples/structure.json | 3 +- 3 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 examples/generics/assoc_items/testcase_add/input.md delete mode 100644 examples/generics/assoc_items/testcase_add/testcase.rs diff --git a/examples/generics/assoc_items/testcase_add/input.md b/examples/generics/assoc_items/testcase_add/input.md deleted file mode 100644 index 0d63e1838d..0000000000 --- a/examples/generics/assoc_items/testcase_add/input.md +++ /dev/null @@ -1,4 +0,0 @@ -Here is a possible implementation of an `Add` trait using associated -types. - -{testcase.play} diff --git a/examples/generics/assoc_items/testcase_add/testcase.rs b/examples/generics/assoc_items/testcase_add/testcase.rs deleted file mode 100644 index f0b2a5fda2..0000000000 --- a/examples/generics/assoc_items/testcase_add/testcase.rs +++ /dev/null @@ -1,51 +0,0 @@ -#[derive(Debug)] -struct I32(i32); -#[derive(Debug)] -struct I64(i64); - -// `Self + Rhs = Sum`: Once the types for `Self` and `Rhs` are -// determined, `Sum` is known. -trait Add { - type Sum; - - // Use `&self` and `&Rhs` so no changes are made to the originals. - // The return shouldn't be a reference. - fn add(&self, rhs: &Rhs) -> Self::Sum; -} - -impl Add for I32 { - type Sum = I32; - - fn add(&self, rhs: &I32) -> Self::Sum { I32(self.0 + rhs.0) } -} - -impl Add for I32 { - type Sum = I64; - - fn add(&self, rhs: &I64) -> Self::Sum { I64(self.0 as i64 + rhs.0) } -} - -impl Add for I64 { - type Sum = I64; - - fn add(&self, rhs: &I32) -> Self::Sum { I64(self.0 + rhs.0 as i64) } -} - -impl Add for I64 { - type Sum = I64; - - fn add(&self, rhs: &I64) -> Self::Sum { I64(self.0 + rhs.0) } -} - - -fn main() { - let i = I32(12); - let j = I64(9); - - println!("{:?} + {:?} = {:?}", &i, &i, i.add(&i)); - - println!("{:?} + {:?} = {:?}", &i, &j, i.add(&j)); - println!("{:?} + {:?} = {:?}", &j, &i, j.add(&i)); - - println!("{:?} + {:?} = {:?}", &j, &j, j.add(&j)); -} diff --git a/examples/structure.json b/examples/structure.json index 234cb4a75f..1b830deb47 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -104,8 +104,7 @@ { "id": "where", "title": "Where clauses", "children": null }, { "id": "assoc_items", "title": "Associated items", "children": [ { "id": "the_problem", "title": "The problem", "children": null }, - { "id": "types", "title": "Associated types", "children": null }, - { "id": "testcase_add", "title": "Testcase: Add", "children": null } + { "id": "types", "title": "Associated types", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ { "id": "testcase_units", "title": "Testcase: unit conversions", "children": null } From 40c871a8fa09cf9355e2e069014dc769db20e695 Mon Sep 17 00:00:00 2001 From: Ivan Kozik Date: Wed, 20 Jan 2016 22:08:25 +0000 Subject: [PATCH 0397/1122] std_misc/process/pipe: remove unnecessary enclosing block --- examples/std_misc/process/pipe/pipe.rs | 29 +++++++++++++------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/examples/std_misc/process/pipe/pipe.rs b/examples/std_misc/process/pipe/pipe.rs index 41747b255b..98e112e127 100644 --- a/examples/std_misc/process/pipe/pipe.rs +++ b/examples/std_misc/process/pipe/pipe.rs @@ -15,23 +15,22 @@ fn main() { Ok(process) => process, }; - { - // Write a string to the `stdin` of `wc`. - // - // `stdin` has type `Option`, but since we know this instance - // must have one, we can directly `unwrap` it. - match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { - Err(why) => panic!("couldn't write to wc stdin: {}", - Error::description(&why)), - Ok(_) => println!("sent pangram to wc"), - } - - // `stdin` gets `drop`ed here, and the pipe is closed. - // - // This is very important, otherwise `wc` wouldn't start processing the - // input we just sent. + // Write a string to the `stdin` of `wc`. + // + // `stdin` has type `Option`, but since we know this instance + // must have one, we can directly `unwrap` it. + match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) { + Err(why) => panic!("couldn't write to wc stdin: {}", + Error::description(&why)), + Ok(_) => println!("sent pangram to wc"), } + // Because `stdin` does not live after the above calls, it is `drop`ed, + // and the pipe is closed. + // + // This is very important, otherwise `wc` wouldn't start processing the + // input we just sent. + // The `stdout` field also has type `Option` so must be unwrapped. let mut s = String::new(); match process.stdout.unwrap().read_to_string(&mut s) { From eda1bdff9d1353395b6720ecf824aeac619f7be7 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 18 Jan 2016 16:36:25 -0800 Subject: [PATCH 0398/1122] Updates to Ch13 - Readability, wording, grammar Renamed 13.7.1 "The problem" -> "The Problem" Removed some unhelpful code and reworded some description to be less redundant between sections --- examples/generics/assoc_items/input.md | 22 ++++++---------- .../generics/assoc_items/the_problem/input.md | 22 ++++++++-------- .../assoc_items/the_problem/problem.rs | 2 +- examples/generics/assoc_items/types/input.md | 25 ++++++++----------- examples/generics/assoc_items/types/types.rs | 4 +-- examples/generics/where/input.md | 25 +++++++++++-------- examples/generics/where/where.rs | 9 +++---- examples/structure.json | 2 +- 8 files changed, 51 insertions(+), 60 deletions(-) diff --git a/examples/generics/assoc_items/input.md b/examples/generics/assoc_items/input.md index 0eb7502e05..b43eb0841b 100644 --- a/examples/generics/assoc_items/input.md +++ b/examples/generics/assoc_items/input.md @@ -1,19 +1,13 @@ -Associated Items is an extension to `trait` generics which encompasses a set -of rules pertaining to [`item`s][items] of various types. It allows `trait`s -to internally define a few new items including: +"Associated Items" refers to a set of rules pertaining to [`item`][items]s +of various types. It is an extension to `trait` generics, and allows +`trait`s to internally define new items. -* `const`s via the keyword `const`. -* `type`s via the keyword `type`. This is called an *output* type. - -Some advantages are: - -* `trait`s now have access to `const`s. -* `type`s get simpler usage patterns when the `trait` is generic over -containers. +One such item is called an *associated type*, providing simpler usage +patterns when the `trait` is generic over its container type. ### See also: -[RFC]( -https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md -) +[RFC][RFC] + [items]: http://doc.rust-lang.org/reference.html#items +[RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md \ No newline at end of file diff --git a/examples/generics/assoc_items/the_problem/input.md b/examples/generics/assoc_items/the_problem/input.md index 3f72793931..a65ec4d2bb 100644 --- a/examples/generics/assoc_items/the_problem/input.md +++ b/examples/generics/assoc_items/the_problem/input.md @@ -1,22 +1,20 @@ -`trait`s generic over container types have strict type specification -requirements. Users of the `trait`s *must* specify all generic types, even -irrelevant ones. +A `trait` that is generic over its container type has type specification +requirements - users of the `trait` *must* specify all of its generic types. -Specifically, examine the `Contains` `trait` and the `difference()` function -which utilizes it. The fact that `Contains` is generic immediately forces -users of the `trait` regardless of need to explicitly state *all* the -`trait`'s generic types. +In the example below, the `Contains` `trait` allows the use of the generic +types `A` and `B`. The trait is then implemented for the `Container` type, +specifying `i32` for `A` and `B` so that it can be used with `fn difference()`. -{problem.play} +Because `Contains` is generic, we are forced to explicitly state *all* of the +generic types for `fn difference()`. In practice, we want a way to express that +`A` and `B` are determined by the *input* `C`. As you will see in the next +section, associated types provide exactly that capability. -The problem is we require a way to express that `A` and `B` are determined -by the *input* `C`. Having to express them as *input* parameters is just -hindering. Associated types provides exactly that capability. +{problem.play} ### See also: [`struct`s][structs], and [`trait`s][traits] - [structs]: /custom_types/structs.html [traits]: /trait.html diff --git a/examples/generics/assoc_items/the_problem/problem.rs b/examples/generics/assoc_items/the_problem/problem.rs index 129fe790fe..6c7d662b77 100644 --- a/examples/generics/assoc_items/the_problem/problem.rs +++ b/examples/generics/assoc_items/the_problem/problem.rs @@ -1,6 +1,6 @@ struct Container(i32, i32); -// A trait which will check to see if 2 items are stored inside of container. +// A trait which checks if 2 items are stored inside of container. // Also retrieves first or last value. trait Contains { fn contains(&self, &A, &B) -> bool; // Explicitly requires `A` and `B`. diff --git a/examples/generics/assoc_items/types/input.md b/examples/generics/assoc_items/types/input.md index 8d20e2baef..754cb91f16 100644 --- a/examples/generics/assoc_items/types/input.md +++ b/examples/generics/assoc_items/types/input.md @@ -1,15 +1,10 @@ -Associated types forms the solution by moving the internal types locally into -the trait to be called *output* types. This shields future users of the trait -from the substantial boilerplate previously required. For example: +The use of "Associated types" improves the overall readability of code +by moving inner types locally into a trait as *output* types. Syntax +for the `trait` definition is as follows: ```rust -// The original trait -trait Contains { - fn contains(&self, &A, &B) -> bool; -} - -// Updated. Now `A` and `B` are defined in the trait via the `type` keyword -// (Note: `type` is this context is different from `type` when used for +// `A` and `B` are defined in the trait via the `type` keyword. +// (Note: `type` in this context is different from `type` when used for // aliases). trait Contains { type A; @@ -20,16 +15,18 @@ trait Contains { } ``` -Users of the `trait` reap the greatest benefits though. This generic function -doesn't need to express `A` or `B` at all: +Note that functions that use the `trait` `Contains` are no longer required +to express `A` or `B` at all: ```rust -// The original +// Without using associated types fn difference(container: &C) -> i32 where C: Contains { ... } -// The updated now no longer has `A` and `B` as requirements. +// Using associated types fn difference(container: &C) -> i32 { ... } ``` +Let's rewrite the example from the previous section using associated types: + {types.play} diff --git a/examples/generics/assoc_items/types/types.rs b/examples/generics/assoc_items/types/types.rs index ec0379cf35..d6ae8f3e95 100644 --- a/examples/generics/assoc_items/types/types.rs +++ b/examples/generics/assoc_items/types/types.rs @@ -1,9 +1,9 @@ struct Container(i32, i32); -// A trait which will check to see if two items are stored inside of container. +// A trait which checks if 2 items are stored inside of container. // Also retrieves first or last value. trait Contains { - // Define generic types here which methods will be able utilize. + // Define generic types here which methods will be able to utilize. type A; type B; diff --git a/examples/generics/where/input.md b/examples/generics/where/input.md index 3aaabe24ea..f71edb3902 100644 --- a/examples/generics/where/input.md +++ b/examples/generics/where/input.md @@ -1,27 +1,30 @@ -A `where` clause is an alternate way to express a bound. It is done by -expressing the bound immediately before the opening `{` instead of at the -types first mention. Some reasons a `where` is useful include: +A bound can also be expressed using a `where` clause immediately +before the opening `{`, rather than at the type's first mention. +Additionally, `where` clauses can apply bounds to arbitrary types, +rather than just to type parameters. -* It is clearer to specify the generic types and bounds separately than -together. For example, these two are equivalent: +Some cases that a `where` clause is useful: + +* When specifying generic types and bounds separately is clearer: ```rust impl MyTrait for YourType {} + +// Expressing bounds with a `where` clause impl MyTrait for YourType where A: TraitB + TraitC, D: TraitE + TraitF {} ``` -* `where` clauses are more expressive than the normal syntax. They can -apply bounds to arbitrary types rather than just type parameters. The -following example cannot be directly expressed without a `where` clause: +* When using a `where` clause is more expressive than using normal syntax. +The `impl` in this example cannot be directly expressed without a `where` clause: {where.play} ### See also: -[RFC][where], [`struct`s][structs], and [`trait`s][traits] +[RFC][where], [`struct`][struct], and [`trait`][trait] -[structs]: /custom_types/structs.html -[traits]: /trait.html +[struct]: /custom_types/structs.html +[trait]: /trait.html [where]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md diff --git a/examples/generics/where/where.rs b/examples/generics/where/where.rs index e112a8e3c6..310547feea 100644 --- a/examples/generics/where/where.rs +++ b/examples/generics/where/where.rs @@ -4,13 +4,12 @@ trait PrintInOption { fn print_in_option(self); } +// Because we would otherwise have to express this as `T: Debug` or +// use another method of indirect approach, this requires a `where` clause: impl PrintInOption for T where - // Without a `where` clause we would have to express this as - // `T: Debug` or use some other method to indirectly approach - // this. The bound we want though is `Option: Debug` because - // that's what being printed. To do otherwise would be to use - // the wrong bound. This requires a `where` clause. Option: Debug { + // We want `Option: Debug` as our bound because that is what's + // being printed. Doing otherwise would be using the wrong bound. fn print_in_option(self) { println!("{:?}", Some(self)); } diff --git a/examples/structure.json b/examples/structure.json index 1b830deb47..4b487514bc 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -103,7 +103,7 @@ { "id": "multi_bounds", "title": "Multiple bounds", "children": null }, { "id": "where", "title": "Where clauses", "children": null }, { "id": "assoc_items", "title": "Associated items", "children": [ - { "id": "the_problem", "title": "The problem", "children": null }, + { "id": "the_problem", "title": "The Problem", "children": null }, { "id": "types", "title": "Associated types", "children": null } ] }, { "id": "phantom", "title": "Phantom types", "children": [ From 42f8816890c80e96e836c1d0091f00978b29bca9 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 19 Jan 2016 16:36:43 -0800 Subject: [PATCH 0399/1122] Updates to Ch13 - 13.8 Phantom types Removed some unnecessary code and reworded for clarity. --- examples/generics/phantom/input.md | 23 ++++++++++----- examples/generics/phantom/phantom.rs | 42 +++++++++++----------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/examples/generics/phantom/input.md b/examples/generics/phantom/input.md index 39e9d0336c..76d49414e3 100644 --- a/examples/generics/phantom/input.md +++ b/examples/generics/phantom/input.md @@ -1,12 +1,21 @@ -A phantom type is a data type which contains extra hidden -generic parameters. These extra parameters hold no storage values. -They are checked statically at compile time and only -at compile time; they have no run-time behavior. +A phantom type parameter is one that doesn't show up at runtime, +but is checked statically (and only) at compile time. + +Data types can use extra generic type parameters to act as markers +or to perform compile-time type checking. These extra parameters +hold no storage values, and have no run-time behavior. + +In the following example, we combine [std::marker::PhantomData] +with the phantom type parameter concept to create tuples containing +different data types. {phantom.play} ### See also: -[Derive](/trait/derive.html), -[struct](/custom_types/structs.html), and -[TupleStructs](/custom_types/structs.html) +[Derive], [struct], and [TupleStructs] + +[Derive]: /trait/derive.html +[struct]: /custom_types/structs.html +[TupleStructs]: /custom_types/structs.html +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/examples/generics/phantom/phantom.rs b/examples/generics/phantom/phantom.rs index 997e63b87f..f7dd716caa 100644 --- a/examples/generics/phantom/phantom.rs +++ b/examples/generics/phantom/phantom.rs @@ -1,47 +1,39 @@ use std::marker::PhantomData; -// Generic tuple struct with same types in both -// generic and definition (A,) -struct Tuple(A,); - -// This tuple is a phantom type. B is a hidden -// parameter. Storage is allocated for generic type A -// yet not for B. Therefore, B cannot be used in computations. +// A phantom tuple struct which is generic over A with hidden parameter B. #[derive(PartialEq)] // Allow equality test for this type struct PhantomTuple(A,PhantomData); -// Similarly, a phantom type struct which is generic over A -// with hidden parameter B +// A phantom type struct which is generic over A with hidden parameter B. #[derive(PartialEq)] // Allow equality test for this type struct PhantomStruct { first: A, phantom: PhantomData } -fn main() { - // instantiate Tuple - let _tuple: Tuple = Tuple('R'); +// Note: Storage is allocated for generic type A, but not for B. +// Therefore, B cannot be used in computations. - // We can create similar types without carrying around extra info - // PhantomTuple specialized to +fn main() { + // Here, `f32` and `f64` + // PhantomTuple type specified as let _tuple1: PhantomTuple = PhantomTuple('Q', PhantomData); - // PhantomTuple specialized to + // PhantomTuple type specified as let _tuple2: PhantomTuple = PhantomTuple('Q', PhantomData); - // Error: type mismatch so these cannot be compared - //println!("_tuple1 == _tuple2 yields: {}", - // _tuple1 == _tuple2); - - // Specialized to + // Type specified as let _struct1: PhantomStruct = PhantomStruct { first: 'Q', phantom: PhantomData, }; - // Specialized to + // Type specified as let _struct2: PhantomStruct = PhantomStruct { first: 'Q', phantom: PhantomData, }; - - // Error: type mismatch so these cannot be compared + + // Compile-time Error! Type mismatch so these cannot be compared: + //println!("_tuple1 == _tuple2 yields: {}", + // _tuple1 == _tuple2); + + // Compile-time Error! Type mismatch so these cannot be compared: //println!("_struct1 == _struct2 yields: {}", // _struct1 == _struct2); -} - +} \ No newline at end of file From f4c3f3aa9399de3fa3ff92f5d243573f7668306f Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 19 Jan 2016 16:59:25 -0800 Subject: [PATCH 0400/1122] Update Ch13 - Phantom types Made mention of phantom types more consistent by referring to the type parameters themselves as phantom type parameters. Also includes small updates to testcase example --- .../generics/phantom/testcase_units/input.md | 23 +++++++++++-------- .../generics/phantom/testcase_units/units.rs | 18 +++++++-------- examples/structure.json | 2 +- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 86a2d32246..262e18ae63 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -1,5 +1,5 @@ A useful method of unit conversions can be examined by implementing `Add` -for a phantom type. The `Add` `trait` is examined below: +with a phantom type parameter. The `Add` `trait` is examined below: ```rust // This construction would impose: `Self + RHS = Output` @@ -23,12 +23,15 @@ The whole implementation: ### See also: -[Borrowing (`&`)](/scope/borrow.html), -[Bounds (`X: Y`)](/trait/bounds.html), -[enum](/custom_types/enum.html), -[impl & self](/fn/methods.html), -[Overloading](/trait/ops.html), -[ref](/scope/borrow/ref.html), -[Traits (`X for Y`)](/trait.html), and -[TupleStructs](/custom_types/structs.html). - +[Borrowing (`&`)], [Bounds (`X: Y`)], [enum], [impl & self], +[Overloading], [ref], [Traits (`X for Y`)], and [TupleStructs]. + +[Borrowing (`&`)]: /scope/borrow.html +[Bounds (`X: Y`)]: /trait/bounds.html +[enum]: /custom_types/enum.html +[impl & self]: /fn/methods.html +[Overloading]: /trait/ops.html +[ref]: /scope/borrow/ref.html +[Traits (`X for Y`)]: /trait.html +[TupleStructs]: /custom_types/structs.html +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index 1002e02640..c23249d809 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -1,13 +1,13 @@ use std::ops::Add; use std::marker::PhantomData; -/// Null enumerations define unit types. +/// Create void enumerations to define unit types. #[derive(Debug, Clone, Copy)] -struct Inch; +enum Inch {} #[derive(Debug, Clone, Copy)] -struct Mm; +enum Mm {} -/// `Length` is phantom type with hidden parameter `Unit`. +/// `Length` is a type with phantom type parameter `Unit`. /// /// `f64` already implements the `Clone` and `Copy` traits. #[derive(Debug, Clone, Copy)] @@ -25,15 +25,15 @@ impl Add for Length { } fn main() { - // Specializes `one_foot` to have hidden parameter `Inch`. + // Specifies `one_foot` to have phantom type parameter `Inch`. let one_foot: Length = Length(12.0, PhantomData); - // `one_meter` has hidden parameter `Mm`. + // `one_meter` has phantom type parameter `Mm`. let one_meter: Length = Length(1000.0, PhantomData); // `+` calls the `add()` method we implemented for `Length`. // - // Since `Length` implements `Clone` + `Copy`, `add()` does not consume - // `one_foot` and `one_meter` but makes a copy of them in `self` and `rhs`. + // Since `Length` implements `Copy`, `add()` does not consume + // `one_foot` and `one_meter` but copies them into `self` and `rhs`. let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; @@ -42,7 +42,7 @@ fn main() { println!("one meter + one_meter = {:?}", two_meters); // Nonsensical operations fail as they should: - // Error: type mismatch. + // Compile-time Error: type mismatch. //let one_feter = one_foot + one_meter; } diff --git a/examples/structure.json b/examples/structure.json index 4b487514bc..39b79faf78 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -106,7 +106,7 @@ { "id": "the_problem", "title": "The Problem", "children": null }, { "id": "types", "title": "Associated types", "children": null } ] }, - { "id": "phantom", "title": "Phantom types", "children": [ + { "id": "phantom", "title": "Phantom type parameters", "children": [ { "id": "testcase_units", "title": "Testcase: unit conversions", "children": null } ] } ] }, From 8d7861a9c84342ff8b2641abde04caabaf401c27 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 11 Jan 2016 15:30:56 -0800 Subject: [PATCH 0401/1122] Updates to Ch13 - reword specialization Also updated examples for readability/grammar changes --- examples/generics/bounds/bounds.rs | 2 +- examples/generics/bounds/input.md | 4 +-- examples/generics/gen_fn/fn.rs | 48 +++++++++++++++------------- examples/generics/gen_fn/input.md | 13 +++++--- examples/generics/gen_trait/trait.rs | 2 +- examples/generics/generics.rs | 4 +-- examples/generics/impl/input.md | 10 +++--- 7 files changed, 45 insertions(+), 38 deletions(-) diff --git a/examples/generics/bounds/bounds.rs b/examples/generics/bounds/bounds.rs index d85cab323c..f652952aaf 100644 --- a/examples/generics/bounds/bounds.rs +++ b/examples/generics/bounds/bounds.rs @@ -14,7 +14,7 @@ struct Rectangle { length: f64, height: f64 } #[allow(dead_code)] struct Triangle { length: f64, height: f64 } -// The generic `T` must implement `Debug`. So regardless +// The generic `T` must implement `Debug`. Regardless // of the type, this will work properly. fn print_debug(t: &T) { println!("{:?}", t); diff --git a/examples/generics/bounds/input.md b/examples/generics/bounds/input.md index 8c4952426d..189bf4cda4 100644 --- a/examples/generics/bounds/input.md +++ b/examples/generics/bounds/input.md @@ -4,14 +4,14 @@ example uses the trait `Display` to print and so it requires `T` to be bound by `Display`; that is, `T` *must* implement `Display`. ```rust -// This function reads: `printer` takes generic type `T` which +// Define a function `printer` that takes a generic type `T` which // must implement trait `Display`. fn printer(t: T) { println!("{}", t); } ``` -One consequence of this is it allows generic instances to access the methods +One consequence is that generic instances are allowed to access the methods of the traits specified in the bounds. For example: {bounds.play} diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs index 4d54f1d473..c3f9192884 100644 --- a/examples/generics/gen_fn/fn.rs +++ b/examples/generics/gen_fn/fn.rs @@ -1,34 +1,38 @@ -struct T; // Concrete type. -struct S(T); // Concrete type. -struct SGen(T); // Generic type. +struct A; // Concrete type `A`. +struct S(A); // Concrete type `S`. +struct SGen(T); // Generic type `SGen`. // These functions all take ownership of the variable passed into // them and immediately go out of scope freeing the variable. -// -// This has no preceding `` so this must be a regular function. -fn die_regular(s: S) {} -// Has a `` but it isn't preceded by `` to make it generic. -// This is a regular function which takes `SGen` which has -// been specialized to type `T` defined at the top. -fn die_generic_specialized_t(s: SGen) {} +// Define a function `reg_fn` that takes an argument `s` of type `S`. +// This has no `` so this must be a non-generic function. +fn reg_fn(s: S) {} -// A regular function taking `SGen` specialized to `i32`. -fn die_generic_specialized_i32(s: SGen) {} +// Define a function `gen_spec_t` that takes an argument `s` of type `SGen` +// that has been explicitly given the type parameter `A`. +// This contains `` but is not preceded by ``, so it is not generic. +fn gen_spec_t(s: SGen) {} -// `` is preceded by ``. This function is generic over `T`. -fn die_generic(s: SGen) {} +// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen` +// that has been explicitly given the type parameter `i32`. +// This function is similarly non-generic. +fn gen_spec_i32(s: SGen) {} + +// Define a function `generic` that takes an argument `s` of type `SGen`. +// Because `SGen` is preceded by ``, this function is generic over `T`. +fn generic(s: SGen) {} fn main() { - // Use the regular functions like normal - die_regular(S(T)); // Concrete type. - die_generic_specialized_t(SGen(T)); // Specialized generic type. - die_generic_specialized_i32(SGen(6)); // Specialized generic type. + // Using the non-generic functions + reg_fn(S(A)); // Concrete type. + gen_spec_t(SGen(A)); // Implicitly specified type parameter `A`. + gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`. - // Explicitly specialize `die_generic()` to `char`. - die_generic::(SGen('a')); + // Explicitly specified type parameter `char` to `generic()`. + generic::(SGen('a')); - // Implicitly specialize `die_generic()` to `char`. - die_generic(SGen('c')); + // Implicitly specified type parameter `char` to `generic()`. + generic(SGen('c')); } diff --git a/examples/generics/gen_fn/input.md b/examples/generics/gen_fn/input.md index c66a323e1f..c6d37aeb97 100644 --- a/examples/generics/gen_fn/input.md +++ b/examples/generics/gen_fn/input.md @@ -1,9 +1,12 @@ -The same set of rules can be applied to functions: a type `T` is only -generic if it has been preceded by ``. This allows functions to have -a variety of forms, some which may have surprising consequences. +The same set of rules can be applied to functions: a type `T` becomes +generic when preceded by ``. -Generic function usage also sometimes requires explicitly specializing -the call. An explicitly specialized function call looks like: +Using generic functions sometimes requires explicitly specifying type +parameters. This may be if the function is called where the return type +is generic, or if the compiler doesn't have enough information to infer +the necessary type parameters. + +A function call with explicitly specified type parameters looks like: `fun::()`. {fn.play} diff --git a/examples/generics/gen_trait/trait.rs b/examples/generics/gen_trait/trait.rs index d48d35c1b2..abaa12bc5c 100644 --- a/examples/generics/gen_trait/trait.rs +++ b/examples/generics/gen_trait/trait.rs @@ -4,7 +4,7 @@ struct Null; // A trait generic over `T`. trait DoubleDrop { - // It defines a method on the caller type which takes an + // Define a method on the caller type which takes an // additional single parameter `T` and does nothing with it. fn double_drop(self, _: T); } diff --git a/examples/generics/generics.rs b/examples/generics/generics.rs index 7f1f945c3f..14fd2cb6c2 100644 --- a/examples/generics/generics.rs +++ b/examples/generics/generics.rs @@ -15,12 +15,12 @@ fn main() { // `Single` is concrete and explicitly takes `A`. let _s = Single(A); - // Here, `SingleGen` is explicitly specialized. This reads as: // Create a variable `_char` of type `SingleGen` // and give it the value `SingleGen('a')` + // Here, `SingleGen` has a type parameter explicitly specified. let _char: SingleGen = SingleGen('a'); - // `SingleGen` can also be implicitly specialized: + // `SingleGen` can also have a type parameter implicitly specified: let _t = SingleGen(A); // Uses `A` defined at the top. let _i32 = SingleGen(6); // Uses `i32`. let _char = SingleGen('a'); // Uses `char`. diff --git a/examples/generics/impl/input.md b/examples/generics/impl/input.md index fd0f6ffde1..39d8695854 100644 --- a/examples/generics/impl/input.md +++ b/examples/generics/impl/input.md @@ -1,12 +1,12 @@ Similar to functions, implementations require care to remain generic. ```rust -struct S; // A null struct -struct GenericVal(T,); +struct S; // Concrete type `S` +struct GenericVal(T,); // Generic type `GenericVal` -// impl of GenericVal we specifically specialize: -impl GenericVal {} // Specialize to `f32` -impl GenericVal {} // Specialize to `S` defined above +// impl of GenericVal where we explicitly specify type parameters: +impl GenericVal {} // Specify `f32` +impl GenericVal {} // Specify `S` as defined above // `` Must precede the type to remain generic impl GenericVal {} From 7a7a53bbe126b42ae214d0ba13bcea28ad9ae608 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 18 Jan 2016 11:38:42 -0800 Subject: [PATCH 0402/1122] Wording change non-generic -> not generic --- examples/generics/gen_fn/fn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs index c3f9192884..38b41c2782 100644 --- a/examples/generics/gen_fn/fn.rs +++ b/examples/generics/gen_fn/fn.rs @@ -6,7 +6,7 @@ struct SGen(T); // Generic type `SGen`. // them and immediately go out of scope freeing the variable. // Define a function `reg_fn` that takes an argument `s` of type `S`. -// This has no `` so this must be a non-generic function. +// This has no `` so this is not a generic function. fn reg_fn(s: S) {} // Define a function `gen_spec_t` that takes an argument `s` of type `SGen` @@ -16,7 +16,7 @@ fn gen_spec_t(s: SGen) {} // Define a function `gen_spec_i32` that takes an argument `s` of type `SGen` // that has been explicitly given the type parameter `i32`. -// This function is similarly non-generic. +// This function is also not generic. fn gen_spec_i32(s: SGen) {} // Define a function `generic` that takes an argument `s` of type `SGen`. From 5a1faa7f91cda7e9c0d0e369dc974a6247ee9496 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 20 Jan 2016 11:16:14 -0800 Subject: [PATCH 0403/1122] Reworded line 14 in fn.rs "Because A has not been specified as a generic type parameter for gen_spec_t, it is not generic" --- examples/generics/gen_fn/fn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs index 38b41c2782..77a53db92b 100644 --- a/examples/generics/gen_fn/fn.rs +++ b/examples/generics/gen_fn/fn.rs @@ -10,8 +10,8 @@ struct SGen(T); // Generic type `SGen`. fn reg_fn(s: S) {} // Define a function `gen_spec_t` that takes an argument `s` of type `SGen` -// that has been explicitly given the type parameter `A`. -// This contains `` but is not preceded by ``, so it is not generic. +// that has been explicitly given the type parameter `A`. Because A has not +// been specified as a generic type parameter for gen_spec_t, it is not generic. fn gen_spec_t(s: SGen) {} // Define a function `gen_spec_i32` that takes an argument `s` of type `SGen` From d9a20aba743e75f5df9e964ae5c31dfb2d9cae72 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 21 Jan 2016 17:40:39 -0800 Subject: [PATCH 0404/1122] Updates to Ch14 - Rewording, grammar, examples Simplified some wording, changed emphases on a few points for readability, added some context --- examples/scope/input.md | 5 +++-- examples/scope/move/input.md | 16 ++++++++++------ examples/scope/move/move.rs | 24 +++++++++++------------- examples/scope/move/mut/mut.rs | 4 ++-- examples/scope/raii/input.md | 23 +++++++++++++++-------- examples/scope/raii/raii.rs | 20 +++++++++++--------- 6 files changed, 52 insertions(+), 40 deletions(-) diff --git a/examples/scope/input.md b/examples/scope/input.md index 7f75ed1775..db6a64dd1a 100644 --- a/examples/scope/input.md +++ b/examples/scope/input.md @@ -1,2 +1,3 @@ -Scoping plays an important part which relates directly to how ownership, -borrowing, and lifetimes play out. +Scopes play an important part in ownership, borrowing, and lifetimes. +That is, they indicate to the compiler when borrows are valid, when +resources can be freed, and when variables are created or destroyed. diff --git a/examples/scope/move/input.md b/examples/scope/move/input.md index c551bb017c..b5c2259019 100644 --- a/examples/scope/move/input.md +++ b/examples/scope/move/input.md @@ -1,11 +1,15 @@ -Because variables are in charge of freeing their resources (if any), resources -can only have *one* owner, otherwise resources would get freed more than once. +Because variables are in charge of freeing their own resources, +**resources can only have one owner**. This also prevents resources +from being freed more than once. Note that not all variables own +resources (e.g. [references]). -When doing assignments `let x = y`, or passing function arguments by value -`foo(x)`, the *ownership* of the resources, if any, is transferred; this is -known as a "move" in Rust-speak. +When doing assignments (`let x = y`) or passing function arguments by value +(`foo(x)`), the *ownership* of the resources is transferred. In Rust-speak, +this is known as a *move*. After moving resources, the previous owner can no longer be used. This avoids -the creation of *dangling pointers*. +creating dangling pointers. {move.play} + +[references]: /flow_control/match/destructuring/destructure_pointers.html diff --git a/examples/scope/move/move.rs b/examples/scope/move/move.rs index 3c42928aba..efdd5e264f 100644 --- a/examples/scope/move/move.rs +++ b/examples/scope/move/move.rs @@ -1,39 +1,37 @@ // This function takes ownership of the heap allocated memory fn destroy_box(c: Box) { - println!("destroying a box that contains {}", c); + println!("Destroying a box that contains {}", c); - // `c` will be destroyed in this scope, and the memory will be freed + // `c` is destroyed and the memory freed } fn main() { - // Stack allocated integer + // _Stack_ allocated integer let x = 5u32; - // "Copy" `x` into `y`, there are no resources to move + // *Copy* `x` into `y` - no resources are moved let y = x; // Both values can be independently used println!("x is {}, and y is {}", x, y); - // `a` is a pointer to a heap allocated integer + // `a` is a pointer to a _heap_ allocated integer let a = Box::new(5i32); println!("a contains: {}", a); - // "Move" `a` into `b` - // Here's what happens under the hood: the pointer `a` gets copied (*not* - // the data on the heap, just its address) into `b`. Now both are pointers - // to the *same* heap allocated data. But now, `b` *owns* the heap - // allocated data; `b` is now in charge of freeing the memory in the heap. + // *Move* `a` into `b` let b = a; - - // After the previous move, `a` can no longer be used + // The pointer address of `a` is copied (not the data) into `b`. + // Both are now pointers to the same heap allocated data, but + // `b` now owns it. + // Error! `a` can no longer access the data, because it no longer owns the // heap memory //println!("a contains: {}", a); // TODO ^ Try uncommenting this line - // "Move" `b` into the function; `b` gives up ownership of the heap data + // This function takes ownership of the heap allocated memory from `b` destroy_box(b); // Since the heap memory has been freed at this point, this action would diff --git a/examples/scope/move/mut/mut.rs b/examples/scope/move/mut/mut.rs index 1de28eb697..f9346467fa 100644 --- a/examples/scope/move/mut/mut.rs +++ b/examples/scope/move/mut/mut.rs @@ -6,10 +6,10 @@ fn main() { // Mutability error //*immutable_box = 4; - // Hand over the box, changing the mutability + // *Move* the box, changing the ownership (and mutability) let mut mutable_box = immutable_box; - println!("mutable_box contained {}", mutable_box); + println!("mutable_box contains {}", mutable_box); // Modify the contents of the box *mutable_box = 4; diff --git a/examples/scope/raii/input.md b/examples/scope/raii/input.md index 157ce87c0d..e504f0054f 100644 --- a/examples/scope/raii/input.md +++ b/examples/scope/raii/input.md @@ -1,13 +1,14 @@ -Variables in Rust do more than just hold data in the stack: they can also *own* -resources, e.g. `Box` owns memory in the heap. Because Rust enforces the -[RAII][raii] -discipline, whenever an object goes out of scope, its destructor is called -and the resources *owned* by it are freed. This behavior shields against -*resource leak* bugs. +Variables in Rust do more than just hold data in the stack: they also *own* +resources, e.g. `Box` owns memory in the heap. Rust enforces [RAII][raii] +(Resource Acquisition Is Initialization), so whenever an object goes out of +scope, its destructor is called and its owned resources are freed. + +This behavior shields against *resource leak* bugs, so you'll never have to +manually free memory or worry about memory leaks again! Here's a quick showcase: {raii.play} -Don't take my word for it, let's check using `valgrind`: +Of course, we can double check for memory errors using [`valgrind`][valgrind]: ``` $ rustc raii.rs && valgrind ./raii @@ -27,6 +28,12 @@ $ rustc raii.rs && valgrind ./raii ==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) ``` -You'll never have to manually free memory or worry about memory leaks again! +No leaks here! + +### See also: + +[Box][box] [raii]: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization +[box]: /std/box.html +[valgrind]: http://valgrind.org/info/ \ No newline at end of file diff --git a/examples/scope/raii/raii.rs b/examples/scope/raii/raii.rs index 50bbba244f..6c5ceff37d 100644 --- a/examples/scope/raii/raii.rs +++ b/examples/scope/raii/raii.rs @@ -1,26 +1,28 @@ +// raii.rs fn create_box() { // Allocate an integer on the heap - let _function_box = Box::new(3i32); + let box1 = Box::new(3i32); - // `_function_box` gets destroyed here, memory gets freed + // `box1` is destroyed here, and memory gets freed } fn main() { // Allocate an integer on the heap - let _boxed_int = Box::new(5i32); + let box2 = Box::new(5i32); - // new (smaller) scope + // A nested scope: { - // Another heap allocated integer - let _short_lived_box = Box::new(4i32); + // Allocate an integer on the heap + let box3 = Box::new(4i32); - // `_short_lived_box` gets destroyed here, memory gets freed + // `box3` is destroyed here, and memory gets freed } - // Create lots of boxes + // Creating lots of boxes just for fun + // There's no need to manually free memory! for _ in 0u32..1_000 { create_box(); } - // `_boxed_int` gets destroyed here, memory gets freed + // `box2` is destroyed here, and memory gets freed } From 32cd1ec0859bdf6d53bd17b6f075626c515c4810 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 25 Jan 2016 23:27:05 -0800 Subject: [PATCH 0405/1122] Updates to Ch14.3 - Borrowing Grammar, readability, variable name changes, some reordering of text/examples --- examples/scope/borrow/alias/alias.rs | 8 +++--- examples/scope/borrow/alias/input.md | 4 +-- examples/scope/borrow/borrow.rs | 27 ++++++++++--------- examples/scope/borrow/freeze/freeze.rs | 16 ++++++------ examples/scope/borrow/freeze/input.md | 4 +-- examples/scope/borrow/input.md | 12 ++++----- examples/scope/borrow/mut/input.md | 12 ++++++--- examples/scope/borrow/mut/mut.rs | 36 +++++++++++++------------- examples/scope/borrow/ref/input.md | 3 ++- examples/scope/borrow/ref/ref.rs | 23 ++++++++++------ 10 files changed, 80 insertions(+), 65 deletions(-) diff --git a/examples/scope/borrow/alias/alias.rs b/examples/scope/borrow/alias/alias.rs index 70919bd7f9..b3bb86f2cf 100644 --- a/examples/scope/borrow/alias/alias.rs +++ b/examples/scope/borrow/alias/alias.rs @@ -12,7 +12,7 @@ fn main() { borrowed_point.x, another_borrow.y, point.z); // Error! Can't borrow point as mutable because it's currently - // borrowed as immutable + // borrowed as immutable. //let mutable_borrow = &mut point; // TODO ^ Try uncommenting this line @@ -24,13 +24,15 @@ fn main() { // Change data via mutable reference mutable_borrow.x = 5; + mutable_borrow.y = 2; + mutable_borrow.z = 1; // Error! Can't borrow `point` as immutable because it's currently - // borrowed as mutable + // borrowed as mutable. //let y = &point.y; // TODO ^ Try uncommenting this line - // Error! Can't print, because println! takes an immutable reference + // Error! Can't print because `println!` takes an immutable reference. //println!("Point Z coordinate is {}", point.z); // TODO ^ Try uncommenting this line diff --git a/examples/scope/borrow/alias/input.md b/examples/scope/borrow/alias/input.md index 438029996d..4016773eb9 100644 --- a/examples/scope/borrow/alias/input.md +++ b/examples/scope/borrow/alias/input.md @@ -1,6 +1,6 @@ Data can be immutably borrowed any number of times, but while immutably -borrowed, the original data can't be mutably borrowed. On the other side, +borrowed, the original data can't be mutably borrowed. On the other hand, only *one* mutable borrow is allowed at a time. The original data can be -borrowed again after the mutable reference goes out of scope. +borrowed again only *after* the mutable reference goes out of scope. {alias.play} diff --git a/examples/scope/borrow/borrow.rs b/examples/scope/borrow/borrow.rs index 5eea9acdbf..5f52585f6a 100644 --- a/examples/scope/borrow/borrow.rs +++ b/examples/scope/borrow/borrow.rs @@ -1,35 +1,34 @@ -// This function takes ownership of the box +// This function takes ownership of a box and destroys it fn eat_box(boxed_int: Box) { - println!("destroying box that contains {}", boxed_int); + println!("Destroying box that contains {}", boxed_int); } -// This function borrows an i32 instead -fn peep_inside_box(borrowed_int: &i32) { +// This function borrows an i32 +fn borrow_box(borrowed_int: &i32) { println!("This int is: {}", borrowed_int); } fn main() { - // A boxed integer + // Create a boxed integer let boxed_int = Box::new(5); - // Borrow the contents of the box, ownership is not taken - peep_inside_box(&boxed_int); - - // The contents can be borrowed again - peep_inside_box(&boxed_int); + // Borrow the contents of the box. Ownership is not taken, + // so the contents can be borrowed again. + borrow_box(&boxed_int); + borrow_box(&boxed_int); { // Take a reference to the data contained inside the box let _ref_to_int: &i32 = &boxed_int; - // Error! Can't destroy boxed_int, while the inner value has been - // borrowed + // Error! + // Can't destroy `boxed_int` while the inner value is borrowed. eat_box(boxed_int); // FIXME ^ Comment out this line - // `_ref_to_int` goes out of scope + // `_ref_to_int` goes out of scope and is no longer borrowed. } - // Give up ownership of the box + // Box can now give up ownership to `eat_box` and be destroyed eat_box(boxed_int); } diff --git a/examples/scope/borrow/freeze/freeze.rs b/examples/scope/borrow/freeze/freeze.rs index 16a466d792..9b9658846e 100644 --- a/examples/scope/borrow/freeze/freeze.rs +++ b/examples/scope/borrow/freeze/freeze.rs @@ -1,17 +1,17 @@ fn main() { - let mut _integer = 5i32; + let mut mutable_integer = 7i32; { - // Borrow `integer` - let _ref_to_integer = &_integer; + // Borrow `mutable_integer` + let large_integer = &mutable_integer; - // Error! `integer` is frozen in this scope - _integer = 4; + // Error! `mutable_integer` is frozen in this scope + mutable_integer = 50; // FIXME ^ Comment out this line - // `ref_to_integer` goes out of scope + // `large_integer` goes out of scope } - // Ok! `integer` is not frozen in this scope - _integer = 4; + // Ok! `mutable_integer` is not frozen in this scope + mutable_integer = 3; } diff --git a/examples/scope/borrow/freeze/input.md b/examples/scope/borrow/freeze/input.md index ca10763179..9a57041c08 100644 --- a/examples/scope/borrow/freeze/input.md +++ b/examples/scope/borrow/freeze/input.md @@ -1,4 +1,4 @@ -When data is borrowed, it also *freezes*. *Frozen* data can't be modified via -the original object, until all the references to it go out of scope. +When data is immutably borrowed, it also *freezes*. *Frozen* data can't be +modified via the original object until all references to it go out of scope: {freeze.play} diff --git a/examples/scope/borrow/input.md b/examples/scope/borrow/input.md index c256dead12..c9bd8265d2 100644 --- a/examples/scope/borrow/input.md +++ b/examples/scope/borrow/input.md @@ -1,9 +1,9 @@ -Most of the time, we'd like to access some data without taking ownership over -it. To accomplish this, Rust provides a *borrowing* mechanism. Instead of +Most of the time, we'd like to access data without taking ownership over +it. To accomplish this, Rust uses a *borrowing* mechanism. Instead of passing objects by-value (`T`), objects can be passed by reference (`&T`). -{borrow.play} +The compiler statically guarantees (via its borrow checker) that references +*always* point to valid objects. That is, while references to an object +exist, the object cannot be destroyed. -The compiler statically guarantees that references *always* point to valid -objects, via its borrow checker. For example, the original object can't be -destroyed, while references to it exists. +{borrow.play} diff --git a/examples/scope/borrow/mut/input.md b/examples/scope/borrow/mut/input.md index c3370d6832..ed07ed1c2e 100644 --- a/examples/scope/borrow/mut/input.md +++ b/examples/scope/borrow/mut/input.md @@ -1,5 +1,11 @@ -`&T` borrows the data via an immutable reference, and the borrower can read the -data but not modify it. Mutable data can be mutably borrowed via a mutable -reference `&mut T`, giving read/write access to the borrower. +Mutable data can be mutably borrowed using `&mut T`. This is called +a *mutable reference* and gives read/write access to the borrower. +In contrast, `&T` borrows the data via an immutable reference, and +the borrower can read the data but not modify it: {mut.play} + +### See Also +[`static`][static] + +[static]: scope/lifetime/static_lifetime.html diff --git a/examples/scope/borrow/mut/mut.rs b/examples/scope/borrow/mut/mut.rs index b126b572fa..8c4399330d 100644 --- a/examples/scope/borrow/mut/mut.rs +++ b/examples/scope/borrow/mut/mut.rs @@ -9,37 +9,37 @@ struct Book { // This function takes a reference to a book fn borrow_book(book: &Book) { - println!("I borrowed {} {} edition", book.title, book.year); + println!("I immutably borrowed {} - {} edition", book.title, book.year); } -// This function takes a reference to a mutable book +// This function takes a reference to a mutable book and changes `year` to 2014 fn new_edition(book: &mut Book) { - // the fields of the book can be modified book.year = 2014; + println!("I mutably borrowed {} - {} edition", book.title, book.year); } fn main() { - // An immutable Book - let geb = Book { + // Create an immutable Book named `immutabook` + let immutabook = Book { // string literals have type `&'static str` author: "Douglas Hofstadter", title: "Gödel, Escher, Bach", year: 1979, }; - // Immutably borrow `geb` - borrow_book(&geb); - - // Error! Can't borrow an immutable object as mutable - new_edition(&mut geb); - // FIXME ^ Comment out this line - - // `mutable_geb` is a mutable copy of `geb` - let mut mutable_geb = geb; + // Create a mutable copy of `immutabook` and call it `mutabook` + let mut mutabook = immutabook; + + // Immutably borrow an immutable object + borrow_book(&immutabook); + // Immutably borrow a mutable object + borrow_book(&mutabook); + // Borrow a mutable object as mutable - new_edition(&mut mutable_geb); - - // Mutable objects can be immutably borrowed - borrow_book(&mutable_geb); + new_edition(&mut mutabook); + + // Error! Cannot borrow an immutable object as mutable + new_edition(&mut immutabook); + // FIXME ^ Comment out this line } diff --git a/examples/scope/borrow/ref/input.md b/examples/scope/borrow/ref/input.md index 7eca8f7256..d65deef065 100644 --- a/examples/scope/borrow/ref/input.md +++ b/examples/scope/borrow/ref/input.md @@ -1,4 +1,5 @@ When doing pattern matching or destructuring via the `let` binding, the `ref` -keyword can be used to take references to the fields of a struct/tuple. +keyword can be used to take references to the fields of a struct/tuple. The +example below shows a few instances where this can be useful: {ref.play} diff --git a/examples/scope/borrow/ref/ref.rs b/examples/scope/borrow/ref/ref.rs index 2079e61e3c..ac31664526 100644 --- a/examples/scope/borrow/ref/ref.rs +++ b/examples/scope/borrow/ref/ref.rs @@ -2,7 +2,7 @@ struct Point { x: i32, y: i32 } fn main() { - let c = 'y'; + let c = 'Q'; // A `ref` borrow on the left side of an assignment is equivalent to // an `&` borrow on the right side. @@ -15,10 +15,10 @@ fn main() { // `ref` is also valid when destructuring a struct. let _copy_of_x = { - // `ref_to_x` is a reference to the `x` field of `point` + // `ref_to_x` is a reference to the `x` field of `point`. let Point { x: ref ref_to_x, y: _ } = point; - // Return a copy of the `x` field of `point` + // Return a copy of the `x` field of `point`. *ref_to_x }; @@ -26,17 +26,24 @@ fn main() { let mut mutable_point = point; { - // `ref` can be paired with `mut` to take mutable references + // `ref` can be paired with `mut` to take mutable references. let Point { x: _, y: ref mut mut_ref_to_y } = mutable_point; - // Mutate the `y` field of `mutable_point`, via a mutable reference + // Mutate the `y` field of `mutable_point` via a mutable reference. *mut_ref_to_y = 1; } println!("point is ({}, {})", point.x, point.y); println!("mutable_point is ({}, {})", mutable_point.x, mutable_point.y); - let tuple = (Box::new(5u32), 3u32); - - println!("tuple is {:?}", tuple); + // A mutable tuple that includes a pointer + let mut mutable_tuple = (Box::new(5u32), 3u32); + + { + // Destructure `mutable_ tuple` to change the value of `last`. + let (_, ref mut last) = mutable_tuple; + *last = 2u32; + } + + println!("tuple is {:?}", mutable_tuple); } From 0fa350b0ae9c0bb3ff44362a69cde7bb800c0cf2 Mon Sep 17 00:00:00 2001 From: viod Date: Wed, 27 Jan 2016 23:07:00 +0100 Subject: [PATCH 0406/1122] hello/input: fix typo --- examples/hello/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello/input.md b/examples/hello/input.md index d45ea7d222..9e2f508dc5 100644 --- a/examples/hello/input.md +++ b/examples/hello/input.md @@ -25,7 +25,7 @@ line with a second `println!` macro so that the output shows: ``` Hello World! -I'm a Rustacian! +I'm a Rustacean! ``` [macros]: ./macros.html From 25cc74fcc1ee85148fc32d9170558c4532a3400b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 1 Feb 2016 14:07:13 -0800 Subject: [PATCH 0407/1122] Add links to generics chapter --- examples/fn/closures/anonymity/input.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/fn/closures/anonymity/input.md b/examples/fn/closures/anonymity/input.md index 8f91c777d6..def2f341bf 100644 --- a/examples/fn/closures/anonymity/input.md +++ b/examples/fn/closures/anonymity/input.md @@ -1,6 +1,6 @@ Closures succinctly capture variables from enclosing scopes. Does this have any consequences? It surely does. Observe how using a closure in a function -requires generics, which is necessary because of how they are defined: +requires [generics], which is necessary because of how they are defined: ```rust // `F` must be generic. @@ -28,6 +28,7 @@ and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or [A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] +[generics]: /generics.html [fn]: http://doc.rust-lang.org/std/ops/trait.Fn.html [fn_mut]: http://doc.rust-lang.org/std/ops/trait.FnMut.html [fn_once]: http://doc.rust-lang.org/std/ops/trait.FnOnce.html From b7808787d4c3199acff563ca6a26f3f9ce20dd46 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 1 Feb 2016 14:08:27 -0800 Subject: [PATCH 0408/1122] Update 14.4 and 14.4.1 Rewording and reorganization for clarity. Reduced information that is redundant with previous section. --- examples/scope/lifetime/explicit/explicit.rs | 50 ++++++++------------ examples/scope/lifetime/explicit/input.md | 41 +++++++++------- examples/scope/lifetime/input.md | 2 +- examples/scope/lifetime/lifetime.rs | 6 +-- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index a5fc09cb03..c8b2eb975f 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -1,24 +1,3 @@ -// This example uses `main()` at the top so it can be read top to -// bottom. `main()` is usually at the bottom. -fn main() { - // Create variables which will be borrowed. - let (four, nine) = (4, 9); - - // Borrows (`&`) of both variables are passed into the function. - // If a borrow is truly a borrow, the variable must be returned, - // otherwise a borrow would be transferring ownership. This means - // no matter what, *any* input which is borrowed via function or - // otherwise, *must* still exist after the borrower ceases. In - // other words, *Rule 2* must be true. - print_refs(&four, &nine); - - // Note that there is no input even though the function specifies - // a lifetime. The sizedness of that lifetime will be determined - // by the caller (which is here) from available lifetimes (scopes). - // Any lifetime chosen will then be larger than that of the function. - failed_borrow(); -} - // `print_refs` takes two references to `i32` which have different // lifetimes `'a` and `'b`. These two lifetimes must both be at // least as long as the function `print_refs`. @@ -26,16 +5,29 @@ fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { println!("x is {} and y is {}", x, y); } -// There are no references to force `'a` to be larger than the -// function, yet `'a` remains larger than the function. +// A function which has no input, but has a lifetime parameter `'a`. fn failed_borrow<'a>() { let _x = 12; - // Attempting to use the lifetime `'a` as an explicit type - // annotation inside the function will fail because the - // lifetime of `&_x` is smaller than `y` has. A small lifetime - // cannot be coerced into a larger one. - // - //let y: &'a i32 = &_x; // ERROR: `_x` does not live long enough + //let y: &'a i32 = &_x; + // Attempting to use the lifetime `'a` as an explicit type annotation + // inside the function will fail because the lifetime of `&_x` is shorter + // than that of `y`. A short lifetime cannot be coerced into a longer one. +} + +fn main() { + // Create variables which will be borrowed. + let (four, nine) = (4, 9); + + // Borrows (`&`) of both variables are passed into the function. + print_refs(&four, &nine); + // Any input which is borrowed must outlive the borrower. + // In other words, the lifetime of `four` and `nine` must + // be longer than that of `print_refs`. + + failed_borrow(); + // `failed_borrow` contains no references to force `'a` to be + // longer than the lifetime of the function, but `'a` is longer. + // Because the lifetime is never constrained, it defaults to `'static`. } diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index cb46870385..3f46a64e8a 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -1,21 +1,31 @@ -The borrow checker utilizes explicit lifetime annotations to reason about -how long references should be valid. Failure to annotate lifetimes[^1] is akin -to banning the borrow checker from validating borrows and so accordingly, -annotation is mandatory. +The borrow checker uses explicit lifetime annotations to determine +how long references should be valid. In cases where lifetimes are not +elided[^1], failure to annotate lifetimes is akin to banning the borrow +checker from validating borrows and annotation is mandatory. +The syntax for explicitly annotating a lifetime uses an apostrophe +character as follows: -Since lifetimes *currently* have no explicit type or name associated with them, -usage will require generics (similar to [closures][anonymity]). Additionally, -a second meaning will be associated with this lifetime syntax. `foo<'a, 'b>` -states: +```rust +foo<'a> +// `foo` has a lifetime parameter `'a` +``` -1. `'a` and `'b` will represent names for lifetimes with non-specifiable -(generic) types. -2. The lifetime of `foo` may not exceed either lifetimes `'a` or `'b`. +Usage of lifetimes requires generics (similar to [closures][anonymity]) +since lifetimes have no type or name associated with them. Additionally, +this lifetime syntax indicates that the lifetime of `foo` may not exceed +that of `'a`. Explicit annotation of a type has the form `&'a T` where +`'a` has already been introduced. -Explicit annotation of a type has the form: `&'a T` where `'a` has already -been introduced. The less obvious of the rules is **Rule 2** whose -importance can usually be directly deduced from borrowing rules. Consider the -following example: +In cases with multiple lifetimes, the syntax is similar: + +```rust +foo<'a, 'b> +// `foo` has lifetime parameters `'a` and `'b` +``` + +In this case, the lifetime of `foo` cannot exceed that of either `'a` *or* `'b`. + +See the following example for explicit lifetime annotation in use: {explicit.play} @@ -25,7 +35,6 @@ following example: [generics][generics] and [closures][closures] - [anonymity]: /fn/closures/anonymity.html [closures]: /fn/closures.html [elision]: /scope/lifetime/elision.html diff --git a/examples/scope/lifetime/input.md b/examples/scope/lifetime/input.md index abb0316a2c..35a5b00691 100644 --- a/examples/scope/lifetime/input.md +++ b/examples/scope/lifetime/input.md @@ -9,5 +9,5 @@ as long as the borrow ends before (inside) the lender is destroyed. {lifetime.play} -You may have noted that no names or types are assigned to label lifetimes. +Note that no names or types are assigned to label lifetimes. This restricts how lifetimes will be able to be used as we will see. diff --git a/examples/scope/lifetime/lifetime.rs b/examples/scope/lifetime/lifetime.rs index d2d2df4eef..16fa623891 100644 --- a/examples/scope/lifetime/lifetime.rs +++ b/examples/scope/lifetime/lifetime.rs @@ -1,6 +1,6 @@ -// Lifetimes are annotated with lines denoting when each variable -// is created and destroyed. `i` has the largest lifetime because it's -// scope entirely encloses both `borrow1` and `borrow2`. The sizedness +// Here, lifetimes are annotated with lines denoting when each variable +// is created and destroyed. `i` has the largest lifetime because its +// scope entirely encloses both `borrow1` and `borrow2`. The "size" // of `borrow1` compared with `borrow2` is irrelevant since they are // disjoint. fn main() { From 071d624a1fd7ff6612a6e4b4e3c72ce845b433d9 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 1 Feb 2016 16:03:58 -0800 Subject: [PATCH 0409/1122] Updated 14.4.2, 14.4.3, 14.4.4 Rewordings for clarification, reduce general wordiness for better readability --- examples/scope/lifetime/fn/fn.rs | 20 +++++++++----------- examples/scope/lifetime/fn/input.md | 8 +++++--- examples/scope/lifetime/methods/methods.rs | 3 +-- examples/scope/lifetime/struct/struct.rs | 4 ++-- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index 29e36850db..143ce9bec4 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -16,19 +16,17 @@ fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { println!("`print_multi`: x is {}, y is {}", x, y); } -// This is invalid. An `i32` would be created, a reference -// would be created, then immediately the data would be -// dropped leaving a reference to invalid data to be returned. -// -// The reason the problem is caught is because of the restriction -// `<'a>` imposes: `'a` must live longer than the function. -//fn invalid_output<'a>() -> &'a i32 { &7 } - -// While returning references without input is banned, returning -// references that have been passed in are perfectly acceptable. -// One restriction is the correct lifetime must be returned. +// Returning references without input is banned, but returning +// references that have been passed in is acceptable. +// One restriction is that the correct lifetime must be returned. fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } +//fn invalid_output<'a>() -> &'a i32 { &7 } +// The above is invalid: 'a` must live longer than the function. +// Here, `&7` would create an `i32`, followed by a reference. +// Then the data is dropped upon exiting the scope, leaving +// a reference to invalid data to be returned. + fn main() { let x = 7; let y = 9; diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md index 29d1a535fa..0d3bf4ac6b 100644 --- a/examples/scope/lifetime/fn/input.md +++ b/examples/scope/lifetime/fn/input.md @@ -1,16 +1,18 @@ -Functions with lifetimes have a few different valid forms. Ignoring -[elision][elision] for the time being, the rules for function parameters are: +Ignoring [elision], function signatures with lifetimes have a few constraints: * any reference *must* have an annotated lifetime. * any reference being returned *must* have the same lifetime as an input or be `static`. +Additionally, note that returning references without input is banned, as it +results in returning references to invalid data. The following example shows +off some valid forms of functions with lifetimes: + {fn.play} ### See also: [functions][fn] - [elision]: /scope/lifetime/elision.html [fn]: /fn.html diff --git a/examples/scope/lifetime/methods/methods.rs b/examples/scope/lifetime/methods/methods.rs index faa47ff0ce..9733c69b1a 100644 --- a/examples/scope/lifetime/methods/methods.rs +++ b/examples/scope/lifetime/methods/methods.rs @@ -1,8 +1,7 @@ -// A regular structure. struct Owner(i32); impl Owner { - // Annotate exactly like a normal function. + // Annotate lifetimes as in a standalone function. fn add_one<'a>(&'a mut self) { self.0 += 1 } fn print<'a>(&'a self) { println!("`print`: {}", self.0); diff --git a/examples/scope/lifetime/struct/struct.rs b/examples/scope/lifetime/struct/struct.rs index abdfcec241..f7e057a9f3 100644 --- a/examples/scope/lifetime/struct/struct.rs +++ b/examples/scope/lifetime/struct/struct.rs @@ -1,9 +1,9 @@ // A type `Borrowed` which houses a reference to an -// `i32`. This reference must outlive the structure. +// `i32`. The reference to `i32` must outlive `Borrowed`. #[derive(Debug)] struct Borrowed<'a>(&'a i32); -// Similarly, both references must outlive this structure. +// Similarly, both references here must outlive this structure. #[derive(Debug)] struct NamedBorrowed<'a> { x: &'a i32, From 97e68d67b8799ce5de9b115511739a106147a6a6 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 1 Feb 2016 16:33:55 -0800 Subject: [PATCH 0410/1122] Updated as per PR comments Changes to wording and some corrections with respect to allowable functions --- examples/scope/lifetime/explicit/explicit.rs | 4 ++-- examples/scope/lifetime/explicit/input.md | 16 +++++++--------- examples/scope/lifetime/fn/fn.rs | 5 ++--- examples/scope/lifetime/fn/input.md | 4 ++-- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/examples/scope/lifetime/explicit/explicit.rs b/examples/scope/lifetime/explicit/explicit.rs index c8b2eb975f..380f447a49 100644 --- a/examples/scope/lifetime/explicit/explicit.rs +++ b/examples/scope/lifetime/explicit/explicit.rs @@ -5,7 +5,7 @@ fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) { println!("x is {} and y is {}", x, y); } -// A function which has no input, but has a lifetime parameter `'a`. +// A function which takes no arguments, but has a lifetime parameter `'a`. fn failed_borrow<'a>() { let _x = 12; @@ -17,7 +17,7 @@ fn failed_borrow<'a>() { } fn main() { - // Create variables which will be borrowed. + // Create variables to be borrowed below. let (four, nine) = (4, 9); // Borrows (`&`) of both variables are passed into the function. diff --git a/examples/scope/lifetime/explicit/input.md b/examples/scope/lifetime/explicit/input.md index 3f46a64e8a..60acf365c6 100644 --- a/examples/scope/lifetime/explicit/input.md +++ b/examples/scope/lifetime/explicit/input.md @@ -1,20 +1,18 @@ The borrow checker uses explicit lifetime annotations to determine how long references should be valid. In cases where lifetimes are not -elided[^1], failure to annotate lifetimes is akin to banning the borrow -checker from validating borrows and annotation is mandatory. -The syntax for explicitly annotating a lifetime uses an apostrophe -character as follows: +elided[^1], Rust requires explicit annotations to determine what the +lifetime of a reference should be. The syntax for explicitly annotating +a lifetime uses an apostrophe character as follows: ```rust foo<'a> // `foo` has a lifetime parameter `'a` ``` -Usage of lifetimes requires generics (similar to [closures][anonymity]) -since lifetimes have no type or name associated with them. Additionally, -this lifetime syntax indicates that the lifetime of `foo` may not exceed -that of `'a`. Explicit annotation of a type has the form `&'a T` where -`'a` has already been introduced. +Similar to [closures][anonymity], using lifetimes requires generics. +Additionally, this lifetime syntax indicates that the lifetime of `foo` +may not exceed that of `'a`. Explicit annotation of a type has the form +`&'a T` where `'a` has already been introduced. In cases with multiple lifetimes, the syntax is similar: diff --git a/examples/scope/lifetime/fn/fn.rs b/examples/scope/lifetime/fn/fn.rs index 143ce9bec4..be1f084fdf 100644 --- a/examples/scope/lifetime/fn/fn.rs +++ b/examples/scope/lifetime/fn/fn.rs @@ -16,9 +16,8 @@ fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) { println!("`print_multi`: x is {}, y is {}", x, y); } -// Returning references without input is banned, but returning -// references that have been passed in is acceptable. -// One restriction is that the correct lifetime must be returned. +// Returning references that have been passed in is acceptable. +// However, the correct lifetime must be returned. fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x } //fn invalid_output<'a>() -> &'a i32 { &7 } diff --git a/examples/scope/lifetime/fn/input.md b/examples/scope/lifetime/fn/input.md index 0d3bf4ac6b..b37ec0dfdb 100644 --- a/examples/scope/lifetime/fn/input.md +++ b/examples/scope/lifetime/fn/input.md @@ -4,8 +4,8 @@ Ignoring [elision], function signatures with lifetimes have a few constraints: * any reference being returned *must* have the same lifetime as an input or be `static`. -Additionally, note that returning references without input is banned, as it -results in returning references to invalid data. The following example shows +Additionally, note that returning references without input is banned if it +would result in returning references to invalid data. The following example shows off some valid forms of functions with lifetimes: {fn.play} From 657428c4ecd2c1ea5cc81ae8268fba07675fd137 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 2 Feb 2016 17:31:23 -0800 Subject: [PATCH 0411/1122] Updated 14.4.5, 14.4.6 Improved readability, changed coercion example to involve less confusion with respect to scoping (and reduce redundancy) --- .../scope/lifetime/lifetime_bounds/bounds.rs | 14 ++++---- .../scope/lifetime/lifetime_bounds/input.md | 12 ++++--- .../lifetime/lifetime_coercion/coercion.rs | 33 ++++++++++--------- .../scope/lifetime/lifetime_coercion/input.md | 6 ++-- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs index d0b88df165..0c9d21d246 100644 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -1,11 +1,11 @@ use std::fmt::Debug; // Trait to bound with. #[derive(Debug)] -// `Ref` contains a reference to type `T` where `T` is unknown -// with an unknown lifetime `'a`. `T` is bounded such that any -// references in `T` must outlive `'a`. In addition, the lifetime -// of `Ref` may not exceed `'a`. struct Ref<'a, T: 'a>(&'a T); +// `Ref` contains a reference to a generic type `T` that has +// an unknown lifetime `'a`. `T` is bounded such that any +// *references* in `T` must outlive `'a`. Additionally, the lifetime +// of `Ref` may not exceed `'a`. // A generic function which prints using the `Debug` trait. fn print(t: T) where @@ -14,7 +14,7 @@ fn print(t: T) where } // Here a reference to `T` is taken where `T` implements -// `Debug` and *all* references in `T` outlive `'a`. In +// `Debug` and all *references* in `T` outlive `'a`. In // addition, `'a` must outlive the function. fn print_ref<'a, T>(t: &'a T) where T: Debug + 'a { @@ -24,7 +24,7 @@ fn print_ref<'a, T>(t: &'a T) where fn main() { let x = 7; let ref_x = Ref(&x); - - print_ref(&ref_x); + print(ref_x); + print_ref(&ref_x); } diff --git a/examples/scope/lifetime/lifetime_bounds/input.md b/examples/scope/lifetime/lifetime_bounds/input.md index 9ea237f770..fd6a0a95c3 100644 --- a/examples/scope/lifetime/lifetime_bounds/input.md +++ b/examples/scope/lifetime/lifetime_bounds/input.md @@ -1,16 +1,20 @@ -Just like generic types can be bounded, lifetimes as generics themselves -utilize bounds also. `:` has a slightly different meaning than in -[generics][bounds] but `+` hasn't changed. Both are described below: +Just like generic types can be bounded, lifetimes (themselves generic) +use bounds as well. The `:` character has a slightly different meaning here, +but `+` is the same. Note how the following read: 1. `T: 'a`: *All* references in `T` must outlive lifetime `'a`. 2. `T: Trait + 'a`: Type `T` must implement trait `Trait` and *all* references in `T` must outlive `'a`. +The example below shows the above syntax in action: + {bounds.play} ### See also: -[generics][generics] and [bounds in generics][bounds] +[generics][generics], [bounds in generics][bounds], and +[multiple bounds in generics][multibounds] [generics]: /generics.html [bounds]: /generics/bounds.html +[multibounds]: /generics/multi_bounds.html \ No newline at end of file diff --git a/examples/scope/lifetime/lifetime_coercion/coercion.rs b/examples/scope/lifetime/lifetime_coercion/coercion.rs index 377cfea17e..a8fc0a3a0f 100644 --- a/examples/scope/lifetime/lifetime_coercion/coercion.rs +++ b/examples/scope/lifetime/lifetime_coercion/coercion.rs @@ -1,21 +1,22 @@ -// `x` is a reference with lifetime `'a` which is larger than `'b`. -// Both `'a` and `'b` are larger than `coerce_first`. Since `'a` is -// larger than `'b`, it may be coerced. -fn coerce_first<'a: 'b, 'b>(x: &'a i32, _: &'b i32) -> &'b i32 { - x +// Here, Rust infers a lifetime that is as short as possible. +// The two references are then coerced to that lifetime. +fn multiply<'a>(first: &'a i32, second: &'a i32) -> i32 { + first * second } -fn main() { - let x = 800; - let y = 8; +// `<'a: 'b, 'b>` reads as lifetime `'a` is at least as long as `'b`. +// Here, we take in an `&'a i32` and return a `&'b i32` as a result of coercion. +fn choose_first<'a: 'b, 'b>(first: &'a i32, _: &'b i32) -> &'b i32 { + first +} - let borrow_big = &x; +fn main() { + let first = 2; // Longer lifetime + { - // This reference is inside a scope and therefore is - // smaller than the other borrow. - let borrow_small = &y; - - let coerced = coerce_first(borrow_big, borrow_small); - println!("`coerced` is {}", coerced); - } + let second = 3; // Shorter lifetime + + println!("The product is {}", multiply(&first, &second)); + println!("{} is the first", choose_first(&first, &second)); + }; } diff --git a/examples/scope/lifetime/lifetime_coercion/input.md b/examples/scope/lifetime/lifetime_coercion/input.md index 5212727897..c96a84c2fd 100644 --- a/examples/scope/lifetime/lifetime_coercion/input.md +++ b/examples/scope/lifetime/lifetime_coercion/input.md @@ -1,4 +1,6 @@ -A lifetime may be coerced into another if the the original is larger than -the new lifetime: +A longer lifetime can be coerced into a shorter one +so that it works inside a scope it normally wouldn't work in. +This comes in the form of inferred coercion by the Rust compiler, +and also in the form of declaring a lifetime difference: {coercion.play} From 9fadca09967228db852003fe2f84bfe621d31ac7 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Wed, 3 Feb 2016 12:11:28 -0800 Subject: [PATCH 0412/1122] Reverted change Reverted reordering of two lines that caused a Travis failure --- examples/scope/lifetime/lifetime_bounds/bounds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs index 0c9d21d246..7862d6f772 100644 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -25,6 +25,6 @@ fn main() { let x = 7; let ref_x = Ref(&x); - print(ref_x); print_ref(&ref_x); + print(ref_x); } From 16889ed652ec4b70e87ff87f5aa8e946ee049987 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 4 Feb 2016 11:58:21 -0800 Subject: [PATCH 0413/1122] Removed extra blank space --- examples/scope/lifetime/lifetime_bounds/bounds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scope/lifetime/lifetime_bounds/bounds.rs b/examples/scope/lifetime/lifetime_bounds/bounds.rs index 7862d6f772..42485cb038 100644 --- a/examples/scope/lifetime/lifetime_bounds/bounds.rs +++ b/examples/scope/lifetime/lifetime_bounds/bounds.rs @@ -24,7 +24,7 @@ fn print_ref<'a, T>(t: &'a T) where fn main() { let x = 7; let ref_x = Ref(&x); - + print_ref(&ref_x); print(ref_x); } From f7dcb16c7dcc4135fc5090167674e82a1e4e127a Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 5 Feb 2016 12:49:39 -0800 Subject: [PATCH 0414/1122] Updated 14.4.7 and 14.4.8 Improved descriptions and reorganized for readability --- examples/scope/lifetime/elision/elision.rs | 20 +++++++------ examples/scope/lifetime/elision/input.md | 11 +++---- .../scope/lifetime/static_lifetime/input.md | 12 ++++---- .../static_lifetime/static_lifetime.rs | 29 ++++++++++--------- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/examples/scope/lifetime/elision/elision.rs b/examples/scope/lifetime/elision/elision.rs index 7bbbec60f9..cdf6b6a419 100644 --- a/examples/scope/lifetime/elision/elision.rs +++ b/examples/scope/lifetime/elision/elision.rs @@ -1,23 +1,25 @@ -// These two functions have essentially identical signatures -// because the compiler implicitly adds the lifetimes to -// the first. -fn elide_input(x: &i32) { - println!("`elide_input`: {}", x) +// `elided_input` and `annotated_input` essentially have identical signatures +// because the lifetime of `elided_input` is elided by the compiler: +fn elided_input(x: &i32) { + println!("`elided_input`: {}", x) } + fn annotated_input<'a>(x: &'a i32) { println!("`annotated_input`: {}", x) } -// Similarly, lifetimes are added implicitly to the first. -fn elide_pass(x: &i32) -> &i32 { x } +// Similarly, `elided_pass` and `annotated_pass` have identical signatures +// because the lifetime is added implicitly to `elided_pass`: +fn elided_pass(x: &i32) -> &i32 { x } + fn annotated_pass<'a>(x: &'a i32) -> &'a i32 { x } fn main() { let x = 3; - elide_input(&x); + elided_input(&x); annotated_input(&x); - println!("`elide_pass`: {}", elide_pass(&x)); + println!("`elided_pass`: {}", elided_pass(&x)); println!("`annotated_pass`: {}", annotated_pass(&x)); } diff --git a/examples/scope/lifetime/elision/input.md b/examples/scope/lifetime/elision/input.md index 9bfa9c6115..b9fd562c8a 100644 --- a/examples/scope/lifetime/elision/input.md +++ b/examples/scope/lifetime/elision/input.md @@ -1,9 +1,10 @@ -Some lifetime patterns are overwelmingly common and so they may be elided -(dropped) and the borrow checker will implicitly add them. Elision exists -solely because these patterns are common; saving typing and easing legibility. +Some lifetime patterns are overwelmingly common and so the borrow checker +will implicitly add them to save typing and to improve readability. +This process of implicit addition is called elision. Elision exists in Rust +solely because these patterns are common. -This section is brief and not comprehensive. See [lifetime elision][elision] -in the book for a more comprehensive treatment. +The following code shows a few examples of elision. For a more comprehensive +description of elision, see [lifetime elision][elision] in the book. {elision.play} diff --git a/examples/scope/lifetime/static_lifetime/input.md b/examples/scope/lifetime/static_lifetime/input.md index 535a12318d..c62556e8c6 100644 --- a/examples/scope/lifetime/static_lifetime/input.md +++ b/examples/scope/lifetime/static_lifetime/input.md @@ -1,11 +1,13 @@ -A `'static` lifetime is one which lasts for the lifetime of the running -program. There are two ways to make a variable with `'static` lifetime: +A `'static` lifetime is longest possible lifetime, and lasts for +the lifetime of the running program. A `'static` lifetime may also be +coerced to a shorter lifetimes. There are two ways to make a variable +with `'static` lifetime, and both are stored in the read-only memory +of the binary: -* Make a `"string"` literal which has type: `&'static str`. * Make a constant with the `static` declaration. +* Make a `string` literal which has type: `&'static str`. -`statics` may also be coerced to smaller lifetimes since they are clearly -larger than most: +See the following example for a display of each method: {static_lifetime.play} diff --git a/examples/scope/lifetime/static_lifetime/static_lifetime.rs b/examples/scope/lifetime/static_lifetime/static_lifetime.rs index aaf0f965f8..8ba00db2c6 100644 --- a/examples/scope/lifetime/static_lifetime/static_lifetime.rs +++ b/examples/scope/lifetime/static_lifetime/static_lifetime.rs @@ -1,28 +1,31 @@ +// Make a constant with `'static` lifetime. static NUM: i32 = 18; -// Return a reference to `NUM` which is coerced to the -// lifetime of `'a` which was used as an input. +// Returns a reference to `NUM` where its `'static` +// lifetime is coerced to that of the input argument. fn coerce_static<'a>(_: &'a i32) -> &'a i32 { &NUM } fn main() { { - // String literals are references to read-only memory - let static_string = "In read-only memory"; + // Make a `string` literal and print it: + let static_string = "I'm in read-only memory"; + println!("static_string: {}", static_string); - // When `_static_string` goes out of scope, we can no longer refer to - // the underlying data, but the string remains in the read-only memory - println!("static_string holds: {}", static_string); + // When `static_string` goes out of scope, the reference + // can no longer be used, but the data remains in the binary. } - println!("but now it's gone."); - println!("NUM: {} is still around though!", NUM); - { - let i = 9; - let coerced_num = coerce_static(&i); + // Make an integer to use for `coerce_static`: + let lifetime_num = 9; + + // Coerce `NUM` to lifetime of `lifetime_num`: + let coerced_static = coerce_static(&lifetime_num); - println!("coerced_num: {}", coerced_num); + println!("coerced_static: {}", coerced_static); } + + println!("NUM: {} stays accessible!", NUM); } From 41d3ea57a28b6a163ca964318ecdb1fe4f223ad9 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 5 Feb 2016 14:07:41 -0800 Subject: [PATCH 0415/1122] Updated 14.4 Reworded description to incorporate language from PR #655. Minor changes to example for clarity --- examples/scope/lifetime/input.md | 16 ++++++----- examples/scope/lifetime/lifetime.rs | 42 ++++++++++++++--------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/examples/scope/lifetime/input.md b/examples/scope/lifetime/input.md index 35a5b00691..6a39515ff6 100644 --- a/examples/scope/lifetime/input.md +++ b/examples/scope/lifetime/input.md @@ -1,11 +1,15 @@ A *lifetime* is a construct the compiler (also called the borrow checker) -uses to ensure all borrows are valid. Specifically, a lifetime starts when -a variable is created and ends when it is destroyed. It can be visualized as -vertical distance but since size is only relevant for subsets and supersets, -scope is considered the more appropriate descriptive term. +uses to ensure all borrows are valid. Specifically, a variable's lifetime +begins when it is created and ends when it is destroyed. While lifetimes +and scopes are often referred to together, they are not the same. -Borrowing (via `&` for example) creates new lifetimes. A borrow is valid -as long as the borrow ends before (inside) the lender is destroyed. +Take, for example, the case where we borrow a variable via `&`. The +borrow has a lifetime that is determined by where it is declared. As a result, +the borrow is valid as long as it ends before the lender is destroyed. However, +the scope of the borrow is determined by where the reference is used. + +In the following example and in the rest of this section, we will see how +lifetimes relate to scopes, as well as how the two differ. {lifetime.play} diff --git a/examples/scope/lifetime/lifetime.rs b/examples/scope/lifetime/lifetime.rs index 16fa623891..501572c2a6 100644 --- a/examples/scope/lifetime/lifetime.rs +++ b/examples/scope/lifetime/lifetime.rs @@ -1,22 +1,22 @@ -// Here, lifetimes are annotated with lines denoting when each variable -// is created and destroyed. `i` has the largest lifetime because its -// scope entirely encloses both `borrow1` and `borrow2`. The "size" -// of `borrow1` compared with `borrow2` is irrelevant since they are -// disjoint. +// Lifetimes are annotated below with lines denoting the creation +// and destruction of each variable. +// `i` has the longest lifetime because its scope entirely encloses +// both `borrow1` and `borrow2`. The duration of `borrow1` compared +// to `borrow2` is irrelevant since they are disjoint. fn main() { - let i = 3; // Lifetime for `i` starts. ───────┐ - // │ - { // │ - let borrow1 = &i; // `borrow1` starts. ──┐│ - // ││ - println!("borrow1: {}", borrow1); // ││ - } // `borrow1 ends. ─────────────────────────┘│ - // │ - // │ - { // │ - let borrow2 = &i; // `borrow2` starts. ──┐│ - // ││ - println!("borrow2: {}", borrow2); // ││ - } // `borrow2` ends. ────────────────────────┘│ - // │ -} // Lifetime ends. ────────────────────────────┘ + let i = 3; // Lifetime for `i` starts. ────────────────┐ + // │ + { // │ + let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ + // ││ + println!("borrow1: {}", borrow1); // ││ + } // `borrow1 ends. ──────────────────────────────────┘│ + // │ + // │ + { // │ + let borrow2 = &i; // `borrow2` lifetime starts. ──┐│ + // ││ + println!("borrow2: {}", borrow2); // ││ + } // `borrow2` ends. ─────────────────────────────────┘│ + // │ +} // Lifetime ends. ─────────────────────────────────────┘ From 75d9d5a8ac37c2946a42b96c3d9c55089c387e1b Mon Sep 17 00:00:00 2001 From: Sonja Biedermann Date: Fri, 12 Feb 2016 15:24:40 +0100 Subject: [PATCH 0416/1122] error/error_vs_absence: fix typo --- examples/error/error_vs_absence/input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/error/error_vs_absence/input.md b/examples/error/error_vs_absence/input.md index ab89d3e7b4..8463926e7d 100644 --- a/examples/error/error_vs_absence/input.md +++ b/examples/error/error_vs_absence/input.md @@ -1,5 +1,5 @@ -Previously, we have used the type `Option` to annotate that absense is a possibility. This -absense sometimes appears as an error, for example when `None` is unwrapped. In the more +Previously, we have used the type `Option` to annotate that absence is a possibility. This +absence sometimes appears as an error, for example when `None` is unwrapped. In the more general case where there may be multiple failure points for a multitude of different reasons, an `Option` can be replaced by the more general `Result` type. A `Result` has these variants: From 9e391081ba53ec6f708696744c3b40acb4451da5 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 15 Feb 2016 14:41:10 -0800 Subject: [PATCH 0417/1122] Update to Ch15; reduced size of example To prevent information overload, the `Dog` struct was removed, and its lessons relocated to `Sheep`. Previously, the example was ~50% longer. --- examples/trait/input.md | 9 ++++-- examples/trait/trait.rs | 71 ++++++++++++----------------------------- 2 files changed, 28 insertions(+), 52 deletions(-) diff --git a/examples/trait/input.md b/examples/trait/input.md index a47bb8bbf8..5cf22ca476 100644 --- a/examples/trait/input.md +++ b/examples/trait/input.md @@ -1,4 +1,9 @@ -A `trait` is a collection of methods declared/defined for an unknown type: -`Self`. Traits can be implemented for any data type. +A `trait` is a collection of methods defined for an unknown type: +`Self`. They can access other methods declared in the same trait. + +Traits can be implemented for any data type. In the example below, +we define `Animal`, a group of methods. The `Animal` `trait` is +then implemented for the `Sheep` data type, allowing the use of +methods from `Animal` with a `Sheep`. {trait.play} diff --git a/examples/trait/trait.rs b/examples/trait/trait.rs index bd9e02c070..dc01a26577 100644 --- a/examples/trait/trait.rs +++ b/examples/trait/trait.rs @@ -1,53 +1,19 @@ +struct Sheep { naked: bool, name: &'static str } + trait Animal { - // Static method signature; `Self` refers to the implementor type + // Static method signature; `Self` refers to the implementor type. fn new(name: &'static str) -> Self; - // Instance methods, only signatures + // Instance method signatures; these will return a string. fn name(&self) -> &'static str; fn noise(&self) -> &'static str; - // A trait can provide default method definitions + // Traits can provide default method definitions. fn talk(&self) { - // These definitions can access other methods declared in the same - // trait println!("{} says {}", self.name(), self.noise()); } } -struct Dog { name: &'static str } - -impl Dog { - fn wag_tail(&self) { - println!("{} wags tail", self.name); - } -} - -// Implement the `Animal` trait for `Dog` -impl Animal for Dog { - // Replace `Self` with the implementor type: `Dog` - fn new(name: &'static str) -> Dog { - Dog { name: name } - } - - fn name(&self) -> &'static str { - self.name - } - - fn noise(&self) -> &'static str { - "woof!" - } - - // Default trait methods can be overridden - fn talk(&self) { - // Traits methods can access the implementor methods - self.wag_tail(); - - println!("{} says {}", self.name, self.noise()); - } -} - -struct Sheep { naked: bool, name: &'static str } - impl Sheep { fn is_naked(&self) -> bool { self.naked @@ -55,18 +21,19 @@ impl Sheep { fn shear(&mut self) { if self.is_naked() { - // Implementor methods can use the implementor's trait methods - println!("{} is already naked!", self.name()); + // Implementor methods can use the implementor's trait methods. + println!("{} is already naked...", self.name()); } else { - println!("{} gets a haircut", self.name); + println!("{} gets a haircut!", self.name); - self.talk(); self.naked = true; } } } +// Implement the `Animal` trait for `Sheep`. impl Animal for Sheep { + // `Self` is the implementor type: `Sheep`. fn new(name: &'static str) -> Sheep { Sheep { name: name, naked: false } } @@ -77,21 +44,25 @@ impl Animal for Sheep { fn noise(&self) -> &'static str { if self.is_naked() { - "baaah" + "baaaaah?" } else { - "baaaaaaaaaaaah" + "baaaaah!" } } + + // Default trait methods can be overridden. + fn talk(&self) { + // For example, we can add some quiet contemplation. + println!("{} pauses briefly... {}", self.name, self.noise()); + } } fn main() { - // Type annotation is necessary in this case + // Type annotation is necessary in this case. let mut dolly: Sheep = Animal::new("Dolly"); - let spike: Dog = Animal::new("Spike"); - // TODO ^ Try removing the type annotations + // TODO ^ Try removing the type annotations. + dolly.talk(); dolly.shear(); - - spike.talk(); dolly.talk(); } From 2f32484787bb428b984e72502e4e686909154c5b Mon Sep 17 00:00:00 2001 From: Danny Hua Date: Mon, 15 Feb 2016 22:21:31 -0800 Subject: [PATCH 0418/1122] Functions/Closures/Examples (8.2.6.2) fix typo Possessive "Its" rather than contraction "It's" --- examples/fn/closures/closure_examples/iter_find/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fn/closures/closure_examples/iter_find/input.md b/examples/fn/closures/closure_examples/iter_find/input.md index 8a08910499..9462ec65db 100644 --- a/examples/fn/closures/closure_examples/iter_find/input.md +++ b/examples/fn/closures/closure_examples/iter_find/input.md @@ -1,5 +1,5 @@ `Iterator::find` is a function which when passed an iterator, will return -the first element which satisfies the predicate as an `Option`. It's +the first element which satisfies the predicate as an `Option`. Its signature: ```rust From 6cde08f2e0f91b335198e00883a2887ea7249eb2 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 16 Feb 2016 15:52:05 -0800 Subject: [PATCH 0419/1122] Updated Ch15.1; readability and minor formatting --- examples/trait/derive/derive.rs | 18 ++++++++---------- examples/trait/derive/input.md | 6 +++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/examples/trait/derive/derive.rs b/examples/trait/derive/derive.rs index 8ef73fa27a..48e5962610 100644 --- a/examples/trait/derive/derive.rs +++ b/examples/trait/derive/derive.rs @@ -1,8 +1,8 @@ -// A tuple struct that can be compared +// `Centimeters`, a tuple struct that can be compared #[derive(PartialEq, PartialOrd)] struct Centimeters(f64); -// A tuple struct that can be printed +// `Inches`, a tuple struct that can be printed #[derive(Debug)] struct Inches(i32); @@ -14,25 +14,23 @@ impl Inches { } } -// A vanilla tuple struct +// `Seconds`, a tuple struct no additional attributes struct Seconds(i32); fn main() { let _one_second = Seconds(1); - // Error! `Seconds` can't be printed, because it doesn't implement the - // `Debug` trait + // Error: `Seconds` can't be printed; it doesn't implement the `Debug` trait //println!("One second looks like: {:?}", _one_second); // TODO ^ Try uncommenting this line - // Error: `Seconds` can't be compared, because it doesn't implement the - // `PartialEq` trait - //let _this_is_true = _one_second == _one_second; + // Error: `Seconds` can't be compared; it doesn't implement the `PartialEq` trait + //let _this_is_true = (_one_second == _one_second); // TODO ^ Try uncommenting this line let foot = Inches(12); - println!("One foot === {:?}", foot); + println!("One foot equals {:?}", foot); let meter = Centimeters(100.0); @@ -43,5 +41,5 @@ fn main() { "bigger" }; - println!("one foot is {} than one meter", cmp); + println!("One foot is {} than one meter.", cmp); } diff --git a/examples/trait/derive/input.md b/examples/trait/derive/input.md index c96a255f33..4efc6513f3 100644 --- a/examples/trait/derive/input.md +++ b/examples/trait/derive/input.md @@ -2,9 +2,7 @@ The compiler is capable of providing basic implementations for some traits via the `#[derive]` [attribute][attribute]. These traits can still be manually implemented if a more complex behavior is required. -{derive.play} - -This is a list of the "derivable" traits: +The following is a list of the "derivable" traits: * Comparison traits: [`Eq`][eq], [`PartialEq`][partial-eq], @@ -21,6 +19,8 @@ This is a list of the "derivable" traits: * [`Debug`][debug], to format a value using the `{:?}` formatter. +{derive.play} + [attribute]: /attribute.html [eq]: http://doc.rust-lang.org/std/cmp/trait.Eq.html [partial-eq]: http://doc.rust-lang.org/std/cmp/trait.PartialEq.html From 81a1ac245cf245ec72afd5c623fd5ca05d84f297 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Thu, 25 Feb 2016 16:31:09 -0800 Subject: [PATCH 0420/1122] Updated Ch15.2 Readability changes to input.md and update to current description in the .rs example. --- examples/trait/ops/input.md | 17 ++++++++++++----- examples/trait/ops/operator.rs | 16 ++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/examples/trait/ops/input.md b/examples/trait/ops/input.md index fb2c783673..6c431b3179 100644 --- a/examples/trait/ops/input.md +++ b/examples/trait/ops/input.md @@ -1,10 +1,17 @@ -In Rust, many of the operators can be overloaded via traits. This is possible -because operators are just sugar for method calls. For example, `a + b` -desugars to `a.add(b)`. This `add` method is part of the `Add` trait; hence, -any implementor of the `Add` trait will be able to use the `+` operator. +In Rust, many of the operators can be overloaded via traits. That is, some operators can +be used to accomplish different tasks based on their input arguments. This is possible +because operators are syntactic sugar for method calls. For example, the `+` operator in +`a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` +trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. + +A list of the traits that overload operators, such as `Add`, are available [here][ops]. {operator.play} -Here is a [list][ops] of the traits that overload operators. +###See Also + +[Add][add], [Syntax Index][syntax] +[add]: http://doc.rust-lang.org/core/ops/trait.Add.html [ops]: http://doc.rust-lang.org/core/ops/ +[syntax]: https://doc.rust-lang.org/book/syntax-index.html diff --git a/examples/trait/ops/operator.rs b/examples/trait/ops/operator.rs index 16036c1758..215ca92bd6 100644 --- a/examples/trait/ops/operator.rs +++ b/examples/trait/ops/operator.rs @@ -1,4 +1,4 @@ -use std::ops::Add; +use std::ops; struct Foo; struct Bar; @@ -9,11 +9,10 @@ struct FooBar; #[derive(Debug)] struct BarFoo; -// The `Add` trait needs two generic parameters: -// * T is the type of the RHS summand, and -// * U is the type of the sum -// This block implements the operation: Foo + Bar = FooBar -impl Add for Foo { +// The `std::ops::Add` trait is used to specify the functionality of `+`. +// Here, we make `Add` - the trait for addition with a RHS of type `Bar`. +// The following block implements the operation: Foo + Bar = FooBar +impl ops::Add for Foo { type Output = FooBar; fn add(self, _rhs: Bar) -> FooBar { @@ -23,9 +22,10 @@ impl Add for Foo { } } -// Addition can be implemented in a non-commutative way +// By reversing the types, we end up implementing non-commutative addition. +// Here, we make `Add` - the trait for addition with a RHS of type `Foo`. // This block implements the operation: Bar + Foo = BarFoo -impl Add for Bar { +impl ops::Add for Bar { type Output = BarFoo; fn add(self, _rhs: Foo) -> BarFoo { From 3ce514119ab377ed8ea62ffb2d2ede6df6083c54 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 4 Mar 2016 21:16:40 -0500 Subject: [PATCH 0421/1122] Update cargo lock --- Cargo.lock | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0739c3564..2132fd5020 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,48 +2,54 @@ name = "update" version = "0.0.1" dependencies = [ - "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.3.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.1.10" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "0.1.6" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.1.41" +version = "0.1.55" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.16" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" From 9c8caabe1f5842261ee794b9dc33b856f4e96123 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 4 Mar 2016 21:23:08 -0500 Subject: [PATCH 0422/1122] VecMap doesn't seem to exist anymore --- examples/std/hash/alt_key_types/input.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/std/hash/alt_key_types/input.md b/examples/std/hash/alt_key_types/input.md index 042f01b520..ccdeb86a43 100644 --- a/examples/std/hash/alt_key_types/input.md +++ b/examples/std/hash/alt_key_types/input.md @@ -3,7 +3,6 @@ This includes: * `bool` (though not very useful since there is only two possible keys) * `int`, `uint`, and all variations thereof -(see [`VecMap`][vecmap] for a more streamlined map implementation keyed by `uint`) * `String` and `&str` (protip: you can have a `HashMap` keyed by `String` and call `.get()` with an `&str`) @@ -27,6 +26,5 @@ let's try making a very simple user logon system: {alt_key_types.play} -[vecmap]: http://doc.rust-lang.org/std/collections/struct.VecMap.html [hash]: http://en.wikipedia.org/wiki/Hash_function [floating]: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems From 3f5dd59fdb9636b64d91f97726de78ca56583d62 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 4 Mar 2016 21:23:29 -0500 Subject: [PATCH 0423/1122] Fix whitespace --- examples/std/hash/alt_key_types/input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/std/hash/alt_key_types/input.md b/examples/std/hash/alt_key_types/input.md index ccdeb86a43..22c647068e 100644 --- a/examples/std/hash/alt_key_types/input.md +++ b/examples/std/hash/alt_key_types/input.md @@ -2,11 +2,11 @@ Any type that implements the `Eq` and `Hash` traits can be a key in `HashMap`. This includes: * `bool` (though not very useful since there is only two possible keys) -* `int`, `uint`, and all variations thereof -* `String` and `&str` (protip: you can have a `HashMap` keyed by `String` +* `int`, `uint`, and all variations thereof +* `String` and `&str` (protip: you can have a `HashMap` keyed by `String` and call `.get()` with an `&str`) -Note that `f32` and `f64` do *not* implement `Hash`, +Note that `f32` and `f64` do *not* implement `Hash`, likely because [floating-point precision errors][floating] would make using them as hashmap keys horribly error-prone. From bac5e7fc361f72257ae985d4ff0b9c4550964171 Mon Sep 17 00:00:00 2001 From: Steve Gury Date: Sat, 5 Mar 2016 15:49:12 -0800 Subject: [PATCH 0424/1122] Prefix unused box variables with "_" This example explains the concept of RAII but never use the `box*` variables. It currently triggers compiler warning, which is confusing for new users and could be easily avoided by prefixing the variables with an underscore. --- examples/scope/raii/raii.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/scope/raii/raii.rs b/examples/scope/raii/raii.rs index 6c5ceff37d..919dda5fc2 100644 --- a/examples/scope/raii/raii.rs +++ b/examples/scope/raii/raii.rs @@ -1,21 +1,21 @@ // raii.rs fn create_box() { // Allocate an integer on the heap - let box1 = Box::new(3i32); + let _box1 = Box::new(3i32); - // `box1` is destroyed here, and memory gets freed + // `_box1` is destroyed here, and memory gets freed } fn main() { // Allocate an integer on the heap - let box2 = Box::new(5i32); + let _box2 = Box::new(5i32); // A nested scope: { // Allocate an integer on the heap - let box3 = Box::new(4i32); + let _box3 = Box::new(4i32); - // `box3` is destroyed here, and memory gets freed + // `_box3` is destroyed here, and memory gets freed } // Creating lots of boxes just for fun @@ -24,5 +24,5 @@ fn main() { create_box(); } - // `box2` is destroyed here, and memory gets freed + // `_box2` is destroyed here, and memory gets freed } From 0e345cb393e46764c94070ffdfbfa615130ec411 Mon Sep 17 00:00:00 2001 From: Steve Gury Date: Sat, 5 Mar 2016 17:21:09 -0800 Subject: [PATCH 0425/1122] Freeze: Prefix variables with "_" to avoid compiler warnings Same reason than in #721 --- examples/scope/borrow/freeze/freeze.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/scope/borrow/freeze/freeze.rs b/examples/scope/borrow/freeze/freeze.rs index 9b9658846e..42dcd8e79c 100644 --- a/examples/scope/borrow/freeze/freeze.rs +++ b/examples/scope/borrow/freeze/freeze.rs @@ -1,17 +1,17 @@ fn main() { - let mut mutable_integer = 7i32; + let mut _mutable_integer = 7i32; { - // Borrow `mutable_integer` - let large_integer = &mutable_integer; + // Borrow `_mutable_integer` + let _large_integer = &_mutable_integer; - // Error! `mutable_integer` is frozen in this scope - mutable_integer = 50; + // Error! `_mutable_integer` is frozen in this scope + _mutable_integer = 50; // FIXME ^ Comment out this line - // `large_integer` goes out of scope + // `_large_integer` goes out of scope } - // Ok! `mutable_integer` is not frozen in this scope - mutable_integer = 3; + // Ok! `_mutable_integer` is not frozen in this scope + _mutable_integer = 3; } From c55bf47fabe854a4563a355ab43c9a0da5925230 Mon Sep 17 00:00:00 2001 From: Steve Webster Date: Thu, 10 Mar 2016 03:14:30 -0500 Subject: [PATCH 0426/1122] More accurate grammar terms in example "Predicate" here would be the entire latter part of the sentence, verb + object. See https://en.wikipedia.org/wiki/Predicate_(grammar) . This is admittedly a petty commit. --- examples/hello/print/print.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/hello/print/print.rs b/examples/hello/print/print.rs index d8f3906357..ee51db8ab7 100644 --- a/examples/hello/print/print.rs +++ b/examples/hello/print/print.rs @@ -11,10 +11,10 @@ fn main() { println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // As can named arguments. - println!("{subject} {verb} {predicate}", - predicate="over the lazy dog", + println!("{subject} {verb} {object}", + object="the lazy dog", subject="the quick brown fox", - verb="jumps"); + verb="jumps over"); // Special formatting can be specified after a `:`. println!("{} of {:b} people know binary, the other half don't", 1, 2); From 98537de257b226e6075be7f9d312cc72d51d994a Mon Sep 17 00:00:00 2001 From: Steve Gury Date: Fri, 11 Mar 2016 13:11:28 -0800 Subject: [PATCH 0427/1122] Remove confusing reuse of variables `a` and `b` The `concat` function takes two strings that represent the filenames of the two file to open. Later in the code, the two closures use `a` and `b` as the name of the argument, this is confusing and could be avoided if we rename the arguments of `concat` to `filename_a` and `filename_b`. --- .../option_with_result/combinator_combinations/result_try.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/error/option_with_result/combinator_combinations/result_try.rs b/examples/error/option_with_result/combinator_combinations/result_try.rs index 738048a815..433699b917 100644 --- a/examples/error/option_with_result/combinator_combinations/result_try.rs +++ b/examples/error/option_with_result/combinator_combinations/result_try.rs @@ -31,8 +31,8 @@ fn get_data(path: &str) -> Result { } // Concat the contents of the two files together into a new `Result`. -fn concat(a: &str, b: &str) -> Result { - let (data_a, data_b) = (get_data(a), get_data(b)); +fn concat(filename_a: &str, filename_b: &str) -> Result { + let (data_a, data_b) = (get_data(filename_a), get_data(filename_b)); data_a.and_then(|a| // Return `Ok` when both `a` and `b` are `Ok`. Otherwise return From 8b21a8ba324d6e4cfd39732ac9722aeb81fb8e0b Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 11 Mar 2016 15:40:34 -0800 Subject: [PATCH 0428/1122] Removed 15.3 due to redundancy Information regarding `where` clauses was moved to 13.4; all other information in 15.3 was already covered. --- examples/generics/bounds/input.md | 21 ++++++----- examples/structure.json | 1 - examples/trait/bounds/bounds.rs | 58 ------------------------------- examples/trait/bounds/input.md | 15 -------- 4 files changed, 13 insertions(+), 82 deletions(-) delete mode 100644 examples/trait/bounds/bounds.rs delete mode 100644 examples/trait/bounds/input.md diff --git a/examples/generics/bounds/input.md b/examples/generics/bounds/input.md index 189bf4cda4..1f5ef52bea 100644 --- a/examples/generics/bounds/input.md +++ b/examples/generics/bounds/input.md @@ -1,4 +1,4 @@ -When working with generics, the types often must use traits as *bounds* to +When working with generics, the type parameters often must use traits as *bounds* to stipulate what functionality a type implements. For example, the following example uses the trait `Display` to print and so it requires `T` to be bound by `Display`; that is, `T` *must* implement `Display`. @@ -11,13 +11,8 @@ fn printer(t: T) { } ``` -One consequence is that generic instances are allowed to access the methods -of the traits specified in the bounds. For example: - -{bounds.play} - -Bounding also restricts the generic from being specialized to -types that do *not* conform to the bounds. That is: +Bounding restricts the generic from being specialized to types that do +*not* conform to the bounds. That is: ```rust struct S(T); @@ -27,10 +22,20 @@ struct S(T); let s = S(vec![1]); ``` +Another effect of bounding is that generic instances are allowed to access the +[methods] of traits specified in the bounds. For example: + +{bounds.play} + +As an additional note, [`where`][where] clauses can also be used to apply bounds in +some cases to be more expressive. + ### See also: [`std::fmt`][fmt], [`struct`s][structs], and [`trait`s][traits] [fmt]: /hello/print.html +[methods]: /fn/methods.html [structs]: /custom_types/structs.html [traits]: /trait.html +[where]: /generics/where.html \ No newline at end of file diff --git a/examples/structure.json b/examples/structure.json index 39b79faf78..baf91938e4 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -135,7 +135,6 @@ { "id": "trait", "title": "Traits", "children": [ { "id": "derive", "title": "Derive", "children": null }, { "id": "ops", "title": "Operator Overloading", "children": null }, - { "id": "bounds", "title": "Bounds", "children": null }, { "id": "drop", "title": "Drop", "children": null }, { "id": "iter", "title": "Iterators", "children": null }, { "id": "clone", "title": "Clone", "children": null } diff --git a/examples/trait/bounds/bounds.rs b/examples/trait/bounds/bounds.rs deleted file mode 100644 index 2522cd3b9a..0000000000 --- a/examples/trait/bounds/bounds.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::ops::{Add, Sub, Mul}; - -#[derive(Debug, Clone, Copy)] -struct Vec2 { - x: T, - y: T, -} - -// Apply bound to `T` at first instance of `T`. `T` -// must implement the `Add` trait. -impl> Add> - for Vec2 { - type Output = Vec2; - - fn add(self, rhs: Vec2) -> Vec2 { - Vec2 { - // `x` and `y` are of type `T`, and implement the `add` method - x: self.x.add(rhs.x), - // The sugary `+` operator can also be used - y: self.y + rhs.y, - } - } -} - -// Bound: `T` must implement the `Sub` trait -impl Sub> for Vec2 - where T: Sub { - type Output = Vec2; - - fn sub(self, rhs: Vec2) -> Vec2 { - Vec2 { - x: self.x - rhs.x, - y: self.y - rhs.y, - } - } -} - -// Bound: `T` must implement *both* the `Add` trait and the `Mul` trait -impl Vec2 - where T: Add + Mul { - fn dot(self, rhs: Vec2) -> T { - (self.x * rhs.x) + (self.y * rhs.y) - } -} - -fn main() { - // Floats implement the `Add`, `Mul` and `Sub` traits - let v1 = Vec2 { x: 1.2_f32, y: 3.4 }; - let v2 = Vec2 { x: 5.6_f32, y: 7.8 }; - - println!("{:?} + {:?} = {:?}", v1, v2, v1 + v2); - println!("{:?} - {:?} = {:?}", v1, v2, v1 - v2); - println!("{:?} ⋅ {:?} = {:?}", v1, v2, v1.dot(v2)); - - // Error! `char` doesn't implement the `Add` trait - println!("{:?}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' }); - // FIXME ^ Comment out this line -} diff --git a/examples/trait/bounds/input.md b/examples/trait/bounds/input.md deleted file mode 100644 index fac77fe76e..0000000000 --- a/examples/trait/bounds/input.md +++ /dev/null @@ -1,15 +0,0 @@ -When working with generics, the type parameters (e.g. `Ty`) may use traits -(e.g. `Tr`) as *bounds* (e.g. `Ty: Tr`, which reads as: `Ty` must implement the -`Tr` trait). Bounding has two effects: - -* Generics instances (`let ty: Ty = (...)`) can now access the methods - (`ty.tr()`) of the traits specified in the bounds. -* The generic can only be specialized for type parameters that conform to the - bounds. - -Bounds are typically applied in one of two ways: - -* At the first instance of the type -* In a `where` clause which directly precedes the `{` in the `impl` - -{bounds.play} From a0a2e23378d6353f01d3f5855a5cf2b1c4d189cf Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 11 Mar 2016 15:42:01 -0800 Subject: [PATCH 0429/1122] Ch15.2 Moved appositive for clarification --- examples/trait/ops/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/trait/ops/input.md b/examples/trait/ops/input.md index 6c431b3179..e3ec9ce758 100644 --- a/examples/trait/ops/input.md +++ b/examples/trait/ops/input.md @@ -4,7 +4,7 @@ because operators are syntactic sugar for method calls. For example, the `+` ope `a + b` calls the `add` method (as in `a.add(b)`). This `add` method is part of the `Add` trait. Hence, the `+` operator can be used by any implementor of the `Add` trait. -A list of the traits that overload operators, such as `Add`, are available [here][ops]. +A list of the traits, such as `Add`, that overload operators are available [here][ops]. {operator.play} From 75c0b5a76187571fcda7bf7de23c2a7cc63804dc Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 11 Mar 2016 16:14:23 -0800 Subject: [PATCH 0430/1122] Ch15.4 Minor grammar changes and added a link Link to the `Drop` trait page was added --- examples/trait/drop/drop.rs | 3 +-- examples/trait/drop/input.md | 15 ++++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/trait/drop/drop.rs b/examples/trait/drop/drop.rs index 5cae6bd099..ff11b47724 100644 --- a/examples/trait/drop/drop.rs +++ b/examples/trait/drop/drop.rs @@ -2,8 +2,7 @@ struct Droppable { name: &'static str, } -// This `drop` implementation doesn't free resources; but instead reports its -// usage via a print to the console +// This trivial implementation of `drop` adds a print to console. impl Drop for Droppable { fn drop(&mut self) { println!("> Dropping {}", self.name); diff --git a/examples/trait/drop/input.md b/examples/trait/drop/input.md index 2e7b4c28d3..a2a0eb157d 100644 --- a/examples/trait/drop/input.md +++ b/examples/trait/drop/input.md @@ -1,9 +1,14 @@ -The `Drop` trait only has one method: `drop`, and this method is called when -an object goes out of scope. The main use of the `Drop` trait is to free the +The [`Drop`][Drop] trait only has one method: `drop`, which is called automatically +when an object goes out of scope. The main use of the `Drop` trait is to free the resources that the implementor instance owns. -`Box`, `Vec`, `String`, `File` and `Process` are some examples of types that -implement the `Drop` trait to free resources. The `Drop` trait can be -implemented for any custom data type. +`Box`, `Vec`, `String`, `File`, and `Process` are some examples of types that +implement the `Drop` trait to free resources. The `Drop` trait can also be +manually implemented for any custom data type. + +The following example adds a print to console to the `drop` function to announce +when it is called. {drop.play} + +[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html \ No newline at end of file From b608923488faace38e141677b6409c353da8c9fe Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 14 Mar 2016 22:12:11 -0700 Subject: [PATCH 0431/1122] Rewording as per PR comments --- examples/generics/bounds/input.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/generics/bounds/input.md b/examples/generics/bounds/input.md index 1f5ef52bea..17b40202c5 100644 --- a/examples/generics/bounds/input.md +++ b/examples/generics/bounds/input.md @@ -11,8 +11,7 @@ fn printer(t: T) { } ``` -Bounding restricts the generic from being specialized to types that do -*not* conform to the bounds. That is: +Bounding restricts the generic to types that conform to the bounds. That is: ```rust struct S(T); From 056bbb65a91b1b9899c7458ce66d774884c252d0 Mon Sep 17 00:00:00 2001 From: Tang Chenglong Date: Tue, 15 Mar 2016 22:52:01 +0800 Subject: [PATCH 0432/1122] Give another Rust's highlight Supply "concurrency" --- examples/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/README.md b/examples/README.md index 839f8b03a9..2b7ab6dee4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,8 +1,8 @@ # Rust by Example -[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. +[Rust][rust] is a modern systems programming language focusing on safety, speed +and concurrency. It accomplishes these goals by being memory safe without using +garbage collection. Rust by Example is a collection of examples that illustrate various Rust concepts and the standard libraries. You can also [check out the source code From 42094eadfb65e06d05632040b2b424fa605f85ac Mon Sep 17 00:00:00 2001 From: jesrui Date: Fri, 18 Mar 2016 22:58:55 +0100 Subject: [PATCH 0433/1122] generics/gen_fn: fix warning about unused variable --- examples/generics/gen_fn/fn.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/generics/gen_fn/fn.rs b/examples/generics/gen_fn/fn.rs index 77a53db92b..01e32d8bec 100644 --- a/examples/generics/gen_fn/fn.rs +++ b/examples/generics/gen_fn/fn.rs @@ -7,21 +7,21 @@ struct SGen(T); // Generic type `SGen`. // Define a function `reg_fn` that takes an argument `s` of type `S`. // This has no `` so this is not a generic function. -fn reg_fn(s: S) {} +fn reg_fn(_s: S) {} // Define a function `gen_spec_t` that takes an argument `s` of type `SGen` // that has been explicitly given the type parameter `A`. Because A has not // been specified as a generic type parameter for gen_spec_t, it is not generic. -fn gen_spec_t(s: SGen) {} +fn gen_spec_t(_s: SGen) {} // Define a function `gen_spec_i32` that takes an argument `s` of type `SGen` // that has been explicitly given the type parameter `i32`. // This function is also not generic. -fn gen_spec_i32(s: SGen) {} +fn gen_spec_i32(_s: SGen) {} // Define a function `generic` that takes an argument `s` of type `SGen`. // Because `SGen` is preceded by ``, this function is generic over `T`. -fn generic(s: SGen) {} +fn generic(_s: SGen) {} fn main() { // Using the non-generic functions From 39bca8f5e1c7548c14f6c34d373ba486a3baa485 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 1 Apr 2016 21:12:51 -0700 Subject: [PATCH 0434/1122] Cleaned up wording Changes made to be consistent with Ch15.5 Iterators --- examples/flow_control/for/input.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/flow_control/for/input.md b/examples/flow_control/for/input.md index 0db1a884c0..1688afe029 100644 --- a/examples/flow_control/for/input.md +++ b/examples/flow_control/for/input.md @@ -1,8 +1,14 @@ -The `for in` construct can be used to iterate an `Iterator`, a lazy value -generator (more details later). One of the easiest ways to create an iterator -is to use the range notation. `a..b` will yield values from `a` (inclusive) to -`b` (exclusive) in steps of one. +The `for in` construct can be used to iterate through an `Iterator`. +One of the easiest ways to create an iterator is to use the range +notation `a..b`. This yields values from `a` (inclusive) to `b` +(exclusive) in steps of one. Let's write FizzBuzz using `for` instead of `while`. {for.play} + +###See also + +[Iterator][iter] + +[iter]: /trait/iter.html \ No newline at end of file From 126912df89519e93ef7b7ac80d498ef563f0c467 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Fri, 1 Apr 2016 21:14:06 -0700 Subject: [PATCH 0435/1122] Readability and grammar changes Shifted some information from .rs to .md to bring out some high points. Reworded some example code for readability. --- examples/trait/iter/input.md | 17 ++++++++++++----- examples/trait/iter/iter.rs | 34 ++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/examples/trait/iter/input.md b/examples/trait/iter/input.md index cf9b3aa1ae..08c3f28d06 100644 --- a/examples/trait/iter/input.md +++ b/examples/trait/iter/input.md @@ -1,9 +1,16 @@ -The `Iterator` trait is used to implement iterators over collections (like -arrays) and lazy value generators. +The `Iterator` trait is used to implement iterators over collections such as arrays. -{iter.play} +The trait requires only a method to be defined for the `next` element, +which may be manually defined in an `impl` block or automatically +defined (as in arrays and ranges). + +As a point of convenience for common situations, the `for` construct +turns some collections into iterators using the [`.into_iterator()`][intoiter] method. -The `Iterator` trait gives access to -[several methods][iter]. +Methods that can be accessed using the `Iterator` trait in addition +to those shown in the example below can be found [here][iter]. + +{iter.play} +[intoiter]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html [iter]: http://doc.rust-lang.org/core/iter/trait.Iterator.html diff --git a/examples/trait/iter/iter.rs b/examples/trait/iter/iter.rs index e260b22377..476c64c0b1 100644 --- a/examples/trait/iter/iter.rs +++ b/examples/trait/iter/iter.rs @@ -3,30 +3,34 @@ struct Fibonacci { next: u32, } -// Implement 'Iterator' for 'Fibonacci' +// Implement `Iterator` for `Fibonacci`. +// The `Iterator` trait only requires a method to be defined for the `next` element. impl Iterator for Fibonacci { type Item = u32; - // The 'Iterator' trait only requires the 'next' method to be defined. The - // return type is 'Option', 'None' is returned when the 'Iterator' is - // over, otherwise the next value is returned wrapped in 'Some' + + // Here, we define the sequence using `.curr` and `.next`. + // The return type is `Option`: + // * When the `Iterator` is finished, `None` is returned. + // * Otherwise, the next value is wrapped in `Some` and returned. fn next(&mut self) -> Option { let new_next = self.curr + self.next; self.curr = self.next; self.next = new_next; - // 'Some' is always returned, this is an infinite value generator + // Since there's no endpoint to a Fibonacci sequence, the `Iterator` + // will never return `None`, and `Some` is always returned. Some(self.curr) } } -// Returns a fibonacci sequence generator +// Returns a Fibonacci sequence generator fn fibonacci() -> Fibonacci { Fibonacci { curr: 1, next: 1 } } fn main() { - // Iterator that generates: 0, 1 and 2 + // `0..3` is an `Iterator` that generates: 0, 1, and 2. let mut sequence = 0..3; println!("Four consecutive `next` calls on 0..3"); @@ -35,22 +39,20 @@ fn main() { println!("> {:?}", sequence.next()); println!("> {:?}", sequence.next()); - // The for construct will iterate an 'Iterator' until it returns 'None'. - // Every 'Some' value is unwrapped and bound to a variable. - println!("Iterate over 0..3 using for"); + // `for` works through an `Iterator` until it returns `None`. + // Each `Some` value is unwrapped and bound to a variable (here, `i`). + println!("Iterate through 0..3 using `for`"); for i in 0..3 { println!("> {}", i); } - // The 'take(n)' method will reduce an iterator to its first 'n' terms, - // which is pretty useful for infinite value generators + // The `take(n)` method reduces an `Iterator` to its first `n` terms. println!("The first four terms of the Fibonacci sequence are: "); for i in fibonacci().take(4) { println!("> {}", i); } - // The 'skip(n)' method will shorten an iterator by dropping its first 'n' - // terms + // The `skip(n)` method shortens an `Iterator` by dropping its first `n` terms. println!("The next four terms of the Fibonacci sequence are: "); for i in fibonacci().skip(4).take(4) { println!("> {}", i); @@ -58,9 +60,9 @@ fn main() { let array = [1u32, 3, 3, 7]; - // The 'iter' method produces an 'Iterator' over an array/slice + // The `iter` method produces an `Iterator` over an array/slice. println!("Iterate the following array {:?}", &array); for i in array.iter() { println!("> {}", i); } -} +} \ No newline at end of file From a084e0f4012e50339fdc1b8d7db37f78f21649b2 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 4 Apr 2016 17:32:59 -0700 Subject: [PATCH 0436/1122] Formatting and readability changes Specific reference to .clone(), and added a link to the rustdoc page for the Clone trait --- examples/trait/clone/clone.rs | 13 ++++++------- examples/trait/clone/input.md | 10 +++++++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/trait/clone/clone.rs b/examples/trait/clone/clone.rs index a4d1cb5b6d..70b67ea740 100644 --- a/examples/trait/clone/clone.rs +++ b/examples/trait/clone/clone.rs @@ -16,7 +16,7 @@ fn main() { println!("original: {:?}", nil); println!("copy: {:?}", copied_nil); - // Instantiate a `Pair` + // Instantiate `Pair` let pair = Pair(Box::new(1), Box::new(2)); println!("original: {:?}", pair); @@ -27,17 +27,16 @@ fn main() { // Error! `pair` has lost it resources //println!("original: {:?}", pair); // TODO ^ Try uncommenting this line - - // "Clone" `moved_pair` into `cloned_pair` (resources included) + + // Clone `moved_pair` into `cloned_pair` (resources are included) let cloned_pair = moved_pair.clone(); - - // `Drop` the original pair + // Drop the original pair using std::mem::drop drop(moved_pair); - // Error! `moved_pair` has been `drop`ed + // Error! `moved_pair` has been dropped //println!("copy: {:?}", moved_pair); // TODO ^ Try uncommenting this line - // Clone can still be used + // The result from .clone() can still be used! println!("clone: {:?}", cloned_pair); } diff --git a/examples/trait/clone/input.md b/examples/trait/clone/input.md index 4cc536156d..ce61cb2384 100644 --- a/examples/trait/clone/input.md +++ b/examples/trait/clone/input.md @@ -1,6 +1,10 @@ When dealing with resources, the default behavior is to transfer them during -assignments or function calls. Sometimes the intention is to make a copy of the -resource. This can be accomplished by calling the `clone` method, defined in -the `Clone` trait. +assignments or function calls. However, sometimes we need to make a +copy of the resource as well. + +The [`Clone`][clone] trait helps us do exactly this. Most commonly, we can +use the `.clone()` method defined by the `Clone` trait. {clone.play} + +[clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html \ No newline at end of file From 33334c179682d2269ae947199c6c82456ef5c637 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Mon, 4 Apr 2016 17:33:37 -0700 Subject: [PATCH 0437/1122] Simplify language and slight reordering --- examples/error/error.rs | 4 ++-- examples/error/input.md | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/examples/error/error.rs b/examples/error/error.rs index 8d3d21193b..bb69620caa 100644 --- a/examples/error/error.rs +++ b/examples/error/error.rs @@ -1,6 +1,6 @@ fn give_princess(gift: &str) { - // Princesses hate snakes so definitely stop the computation while - // she shouts her dislike. + // Princesses hate snakes, so we need to stop if + // she expresses her disapproval! if gift == "snake" { panic!("AAAaaaaa!!!!"); } println!("I love {}s!!!!!", gift); diff --git a/examples/error/input.md b/examples/error/input.md index aa4bb37d4e..fdbd1a9735 100644 --- a/examples/error/input.md +++ b/examples/error/input.md @@ -1,16 +1,21 @@ -Error handling is the process of handling the possibility of failure. For example, failing to -read a file and then continuing to use that *bad* input regardless clearly would be problematic. -Error handling allows us to notice and handle those errors in some explicit fashion, saving the -rest of the program from pollution. +Error handling is the process of handling the possibility of failure. For +example, failing to read a file and then continuing to use that *bad* input +would clearly be problematic. Error handling allows us to notice and handle +those errors in an explicit fashion, saving the rest of the program from +potential issues. -The simplest error handling mechanism we will see is the `panic`; it prints an error message, -starts unwinding the task, and usually exits the program. Consider the following example: +The simplest error handling mechanism we will see is `panic`. It prints an +error message, starts unwinding the task, and usually exits the program. +Consider the following example: {error.play} -This easily shows that we can induce program failure at will but it has a problem: what happens -if the princess is *not* given a gift? Technically, we *could* explicitly test this with a check -against the null string (`""`) the same way as with the snake however this is not reliable. The -problem is that programmers do not habitually make these checks unless required by the compiler. -In order for this to always be reliable, we require the compiler to point out the cases where there -may not be a gift. `str` does not do that for us; we require something else called `Option`. +This shows that we can induce program failure at will, but raises a +question: what happens if the princess is *not* given a gift? We *could* +explicitly test this with a check against the null string (`""`) as we do +with the snake, but this is not reliable. The problem is that programmers do +not habitually test these checks unless required to by the compiler. + +In order for this to be reliable, we'll want the compiler to point out +cases where there may not be a gift. As you'll see in the next section, we +can use `Option` to take care of this condition. From 98c9d3fd0cc4044a068f6da59332ca93fdd2c9cb Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 5 Apr 2016 11:47:16 -0700 Subject: [PATCH 0438/1122] Slight reorganization and comment changes Also address #733 --- examples/fn/closures/input_functions/input.md | 13 +++++++------ .../fn/closures/input_functions/input_functions.rs | 8 +++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/examples/fn/closures/input_functions/input.md b/examples/fn/closures/input_functions/input.md index f63804e3ec..49cf69acae 100644 --- a/examples/fn/closures/input_functions/input.md +++ b/examples/fn/closures/input_functions/input.md @@ -1,12 +1,13 @@ -Since closures are possible as arguments, you might wonder if functions -are possible as well. Indeed they are! The previously mentioned `Fn`, -`FnMut`, and `FnOnce` `traits` all dictate in what fashion a closure captures -variables from the enclosing scope. Because a function can *never* capture -variables, closures are strictly more flexible. Therefore, any function which -can take a closure as an argument can also take a function. +Since closures may be used as arguments, you might wonder if the same can be said +about functions. And indeed they can! However, because a function can +*never* capture variables, closures are strictly more flexible. Therefore, any +function which can take a closure as an argument can also take a function. {input_functions.play} +As an additional note, the `Fn`, `FnMut`, and `FnOnce` `traits` dictate how +a closure captures variables from the enclosing scope. + ### See also: [`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once] diff --git a/examples/fn/closures/input_functions/input_functions.rs b/examples/fn/closures/input_functions/input_functions.rs index b99199f440..3c7c26530a 100644 --- a/examples/fn/closures/input_functions/input_functions.rs +++ b/examples/fn/closures/input_functions/input_functions.rs @@ -1,15 +1,17 @@ -// A function which takes a closure as an argument and calls it. +// Define a function which takes a function as an argument and calls it. fn call_function(f: F) { f() } +// Define a simple function to be used as an input. fn print() { - println!("I'm a function! I can be used like a closure.") + println!("I'm a function!") } fn main() { + // Define a closure similar to the `print()` function above. let closure = || println!("I'm a closure!"); - call_function(closure); + call_function(closure); call_function(print); } \ No newline at end of file From 632bc123a527ef8d7ce0633bc1b14005ac349759 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 5 Apr 2016 11:47:57 -0700 Subject: [PATCH 0439/1122] Grammar and flow changes --- examples/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/README.md b/examples/README.md index 2b7ab6dee4..0a1017055c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,15 +1,15 @@ # Rust by Example -[Rust][rust] is a modern systems programming language focusing on safety, speed +[Rust][rust] is a modern systems programming language focusing on safety, speed, and concurrency. It accomplishes these goals by being memory safe without using garbage collection. -Rust by Example is a collection of examples that illustrate various Rust -concepts and the standard libraries. You can also [check out the source code -for this site][home]. +Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust +concepts and standard libraries. To get even more out of these examples, don't forget +to [install Rust locally][install] and check out the [official docs][std]. +Additionally for the curious, you can also [check out the source code for this site][home]. -Be sure to have Rust [installed][install] and the [docs][std] at hand, and -let's start! +Now let's begin! [rust]: http://www.rust-lang.org/ [install]: http://www.rust-lang.org/install.html From 9a8e2552b50a0cadcb56e96d777cb039b9367609 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 5 Apr 2016 11:48:52 -0700 Subject: [PATCH 0440/1122] Grammar and flow changes Capitalizations, commas, and link reordering --- examples/fn/closures/closure_examples/input.md | 2 +- examples/fn/closures/closure_examples/iter_any/input.md | 2 +- examples/fn/closures/closure_examples/iter_find/input.md | 2 +- examples/fn/closures/input.md | 6 ++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/fn/closures/closure_examples/input.md b/examples/fn/closures/closure_examples/input.md index ee3e8e9676..29bd47f83f 100644 --- a/examples/fn/closures/closure_examples/input.md +++ b/examples/fn/closures/closure_examples/input.md @@ -1 +1 @@ -This section contains a few examples of using closures in the `std` library. \ No newline at end of file +This section contains a few examples of using closures from the `std` library. \ No newline at end of file diff --git a/examples/fn/closures/closure_examples/iter_any/input.md b/examples/fn/closures/closure_examples/iter_any/input.md index d33e2fd867..0780bfb96a 100644 --- a/examples/fn/closures/closure_examples/iter_any/input.md +++ b/examples/fn/closures/closure_examples/iter_any/input.md @@ -21,6 +21,6 @@ pub trait Iterator { ### See also: -[`std::iter::iterator::any`][any] +[`std::iter::Iterator::any`][any] [any]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any diff --git a/examples/fn/closures/closure_examples/iter_find/input.md b/examples/fn/closures/closure_examples/iter_find/input.md index 9462ec65db..00e92c655a 100644 --- a/examples/fn/closures/closure_examples/iter_find/input.md +++ b/examples/fn/closures/closure_examples/iter_find/input.md @@ -21,6 +21,6 @@ pub trait Iterator { ### See also: -[`std::iter::iterator::find`][find] +[`std::iter::Iterator::find`][find] [find]: http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find diff --git a/examples/fn/closures/input.md b/examples/fn/closures/input.md index 9186f9bb3c..45a64f077b 100644 --- a/examples/fn/closures/input.md +++ b/examples/fn/closures/input.md @@ -1,5 +1,5 @@ -Closures[^*] in Rust are functions with a slightly specialized syntax which -can capture the enclosing environment. Their syntax and capabilities make them +Closures in Rust, also called lambdas or anonymous functions, are functions +that can capture the enclosing environment. Their syntax and capabilities make them very convenient for on the fly usage. Some characteristics include: * uses `||` instead of `()` around input variables. @@ -11,5 +11,3 @@ otherwise. * calling a closure is exactly like a function: `call(var)`. {closures.play} - -[^*]: Also called `lambdas` or `anonymous functions`. From 363268da9e58ddb08b584620fa6b8497f0889a41 Mon Sep 17 00:00:00 2001 From: Tomasz Pasternak Date: Wed, 13 Apr 2016 21:31:07 +0200 Subject: [PATCH 0441/1122] EPUB and PDF generation Initial support for PDF and EPUB generation. Implements #270. --- .travis.yml | 4 +++- Makefile | 10 ++++++++-- README.md | 2 +- src/playpen.rs | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index caacc13e64..0ba6bb790b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,9 @@ script: - rustc --version - make - make test - - make book + - make html + - make pdf + - make epub notifications: email: diff --git a/Makefile b/Makefile index af10291f6f..eaf807886b 100644 --- a/Makefile +++ b/Makefile @@ -22,17 +22,23 @@ WHITELIST = examples/attribute/cfg/custom/custom.rs \ srcs = $(filter-out $(WHITELIST),$(shell find examples -name '*.rs')) -.PHONY: all book clean test serve +.PHONY: all html epub pdf clean test serve all: ./setup-stage.sh cargo run -book: node_modules/gitbook +html: node_modules/gitbook $(GITBOOK) build stage ./fix-edit-button.sh ./add-relinks.sh +epub: node_modules/gitbook + $(GITBOOK) epub stage + +pdf: node_modules/gitbook + $(GITBOOK) pdf stage + clean: rm -rf bin stage diff --git a/README.md b/README.md index e73b92dbf9..319c7c7e91 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Run: ``` make all -make book +make html pdf epub make test ``` diff --git a/src/playpen.rs b/src/playpen.rs index ff3e1a2c9f..b211dfc0fa 100644 --- a/src/playpen.rs +++ b/src/playpen.rs @@ -2,7 +2,7 @@ pub fn editor(source: &str) -> String { format!("