Skip to content

Commit d72084b

Browse files
authored
Merge branch 'master' into jsjoeio/108-doc-attribute-examples
2 parents 94ca1f7 + 325a512 commit d72084b

File tree

12 files changed

+135
-69
lines changed

12 files changed

+135
-69
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
book
2+
3+
# Auto-generated files from macOS
4+
.DS_Store

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,4 @@
213213

214214
- [Meta](meta.md)
215215
- [Documentation](meta/doc.md)
216+
- [Playpen](meta/playpen.md)

src/error/multiple_error_types/boxing_errors.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,7 @@ impl fmt::Display for EmptyVec {
2424
}
2525
}
2626
27-
impl error::Error for EmptyVec {
28-
fn description(&self) -> &str {
29-
"invalid first item to double"
30-
}
31-
32-
fn cause(&self) -> Option<&(dyn error::Error)> {
33-
// Generic error, underlying cause isn't tracked.
34-
None
35-
}
36-
}
27+
impl error::Error for EmptyVec {}
3728
3829
fn double_first(vec: Vec<&str>) -> Result<i32> {
3930
vec.first()

src/error/multiple_error_types/define_error_type.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ Rust allows us to define our own error types. In general, a "good" error type:
1616
* Composes well with other errors
1717

1818
```rust,editable
19-
use std::error;
2019
use std::fmt;
2120
2221
type Result<T> = std::result::Result<T, DoubleError>;
@@ -38,14 +37,6 @@ impl fmt::Display for DoubleError {
3837
}
3938
}
4039
41-
// This is important for other errors to wrap this one.
42-
impl error::Error for DoubleError {
43-
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
44-
// Generic error, underlying cause isn't tracked.
45-
None
46-
}
47-
}
48-
4940
fn double_first(vec: Vec<&str>) -> Result<i32> {
5041
vec.first()
5142
// Change the error to our new type.

src/error/multiple_error_types/reenter_question_mark.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,7 @@ impl fmt::Display for EmptyVec {
3838
}
3939
}
4040
41-
impl error::Error for EmptyVec {
42-
fn description(&self) -> &str {
43-
"invalid first item to double"
44-
}
45-
46-
fn cause(&self) -> Option<&error::Error> {
47-
// Generic error, underlying cause isn't tracked.
48-
None
49-
}
50-
}
41+
impl error::Error for EmptyVec {}
5142
5243
// The same structure as before but rather than chain all `Results`
5344
// and `Options` along, we `?` to get the inner value out immediately.

src/meta.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Some topics aren't exactly relevant to how you program but provide you
44
tooling or infrastructure support which just makes things better for
55
everyone. These topics include:
66

7-
* Documentation: Generate library documentation for users via the included
8-
`rustdoc`.
9-
* Testing: Create testsuites for libraries to give confidence that your
10-
library does exactly what it's supposed to.
11-
* Benchmarking: Create benchmarks for functionality to be confident that
12-
they run quickly.
7+
- [Documentation][doc]: Generate library documentation for users via the included
8+
`rustdoc`.
9+
- [Playpen][playpen]: Integrate the Rust Playpen(also known as the Rust Playground) in your documentation.
10+
11+
[doc]: meta/doc.md
12+
[playpen]: meta/playpen.md

src/meta/doc.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ These commands will appropriately invoke `rustdoc` (and `rustc`) as required.
99
## Doc comments
1010

1111
Doc comments are very useful for big projects that require documentation. When
12-
running Rustdoc, these are the comments that get compiled into
12+
running `rustdoc`, these are the comments that get compiled into
1313
documentation. They are denoted by a `///`, and support [Markdown].
1414

1515
```rust,editable,ignore
@@ -32,7 +32,7 @@ impl Person {
3232
///
3333
/// ```
3434
/// // You can have rust code between fences inside the comments
35-
/// // If you pass --test to Rustdoc, it will even test it for you!
35+
/// // If you pass --test to `rustdoc`, it will even test it for you!
3636
/// use doc::Person;
3737
/// let person = Person::new("name");
3838
/// ```
@@ -57,7 +57,7 @@ fn main() {
5757
}
5858
```
5959

60-
To run the tests, first build the code as a library, then tell rustdoc where
60+
To run the tests, first build the code as a library, then tell `rustdoc` where
6161
to find the library so it can link it into each doctest program:
6262

6363
```shell
@@ -103,10 +103,12 @@ Using this tells `rustdoc` not to include this in documentation:
103103
pub use self::async_await::*;
104104
```
105105

106+
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/).
107+
106108
### See also:
107109

108110
* [The Rust Book: Making Useful Documentation Comments][book]
109-
* [The Rustdoc Book][rustdoc-book]
111+
* [The rustdoc Book][rustdoc-book]
110112
* [The Reference: Doc comments][ref-comments]
111113
* [RFC 1574: API Documentation Conventions][api-conv]
112114
* [RFC 1946: Relative links to other items from doc comments (intra-rustdoc links)][intra-links]

src/meta/playpen.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Playpen
2+
3+
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/).
4+
5+
## Using it with `mdbook`
6+
7+
In [`mdbook`][mdbook], you can make code examples playable and editable.
8+
9+
```rust,editable
10+
fn main() {
11+
println!("Hello World!");
12+
}
13+
```
14+
15+
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.
16+
17+
````markdown
18+
```rust,editable
19+
//...place your code here
20+
```
21+
````
22+
23+
## Using it with docs
24+
25+
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].
26+
27+
### See also:
28+
29+
- [The Rust Playground][rust-playground]
30+
- [The next-gen playpen][next-gen-playpen]
31+
- [The rustdoc Book][rustdoc-book]
32+
33+
[rust-playground]: https://play.rust-lang.org/
34+
[next-gen-playpen]: https://github.com/integer32llc/rust-playground/
35+
[mdbook]: https://github.com/rust-lang/mdBook
36+
[official-rust-docs]: https://doc.rust-lang.org/core/
37+
[rustdoc-book]: https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html
38+
[html-playground-url]: https://doc.rust-lang.org/rustdoc/the-doc-attribute.html#html_playground_url

src/scope/lifetime/static_lifetime.md

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
# Static
22

3-
A `'static` lifetime is the longest possible lifetime, and lasts for
4-
the lifetime of the running program. A `'static` lifetime may also be
5-
coerced to a shorter lifetime. There are two ways to make a variable
6-
with `'static` lifetime, and both are stored in the read-only memory
7-
of the binary:
3+
Rust has a few reserved lifetime names. One of those is `'static`. You
4+
might encounter it in two situations:
5+
6+
```rust, editable
7+
// A reference with 'static lifetime:
8+
let s: &'static str = "hello world";
9+
10+
// 'static as part of a trait bound:
11+
fn generic<T>(x: T) where T: 'static {}
12+
```
13+
14+
Both are related but subtly different and this is a common source for
15+
confusion when learning Rust. Here are some examples for each situation:
16+
17+
## Reference lifetime
18+
19+
As a reference lifetime `'static` indicates that the data pointed to by
20+
the reference lives for the entire lifetime of the running program.
21+
It can still be coerced to a shorter lifetime.
22+
23+
There are two ways to make a variable with `'static` lifetime, and both
24+
are stored in the read-only memory of the binary:
825

926
* Make a constant with the `static` declaration.
1027
* Make a `string` literal which has type: `&'static str`.
@@ -15,7 +32,7 @@ See the following example for a display of each method:
1532
// Make a constant with `'static` lifetime.
1633
static NUM: i32 = 18;
1734
18-
// Returns a reference to `NUM` where its `'static`
35+
// Returns a reference to `NUM` where its `'static`
1936
// lifetime is coerced to that of the input argument.
2037
fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
2138
&NUM
@@ -30,7 +47,7 @@ fn main() {
3047
// When `static_string` goes out of scope, the reference
3148
// can no longer be used, but the data remains in the binary.
3249
}
33-
50+
3451
{
3552
// Make an integer to use for `coerce_static`:
3653
let lifetime_num = 9;
@@ -40,13 +57,56 @@ fn main() {
4057
4158
println!("coerced_static: {}", coerced_static);
4259
}
43-
60+
4461
println!("NUM: {} stays accessible!", NUM);
4562
}
4663
```
4764

65+
## Trait bound
66+
67+
As a trait bound, it means the type does not contain any non-static
68+
references. Eg. the receiver can hold on to the type for as long as
69+
they want and it will never become invalid until they drop it.
70+
71+
It's important to understand this means that any owned data always passes
72+
a `'static` lifetime bound, but a reference to that owned data generally
73+
does not:
74+
75+
```rust,editable,compile_fail
76+
use std::fmt::Debug;
77+
78+
fn print_it( input: impl Debug + 'static )
79+
{
80+
println!( "'static value passed in is: {:?}", input );
81+
}
82+
83+
fn use_it()
84+
{
85+
// i is owned and contains no references, thus it's 'static:
86+
let i = 5;
87+
print_it(i);
88+
89+
// oops, &i only has the lifetime defined by the scope of
90+
// use_it(), so it's not 'static:
91+
print_it(&i);
92+
}
93+
```
94+
The compiler will tell you:
95+
```ignore
96+
error[E0597]: `i` does not live long enough
97+
--> src/lib.rs:15:15
98+
|
99+
15 | print_it(&i);
100+
| ---------^^--
101+
| | |
102+
| | borrowed value does not live long enough
103+
| argument requires that `i` is borrowed for `'static`
104+
16 | }
105+
| - `i` dropped here while still borrowed
106+
```
107+
48108
### See also:
49109

50110
[`'static` constants][static_const]
51111

52-
[static_const]: ../../custom_types/constants.md
112+
[static_const]: ../../custom_types/constants.md

src/std_misc/file/create.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,23 @@ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
1414
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
1515
";
1616
17-
use std::error::Error;
1817
use std::fs::File;
1918
use std::io::prelude::*;
2019
use std::path::Path;
2120
2221
fn main() {
23-
let path = Path::new("out/lorem_ipsum.txt");
22+
let path = Path::new("lorem_ipsum.txt");
2423
let display = path.display();
2524
2625
// Open a file in write-only mode, returns `io::Result<File>`
2726
let mut file = match File::create(&path) {
28-
Err(why) => panic!("couldn't create {}: {}", display, why.description()),
27+
Err(why) => panic!("couldn't create {}: {}", display, why),
2928
Ok(file) => file,
3029
};
3130
3231
// Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>`
3332
match file.write_all(LOREM_IPSUM.as_bytes()) {
34-
Err(why) => panic!("couldn't write to {}: {}", display, why.description()),
33+
Err(why) => panic!("couldn't write to {}: {}", display, why),
3534
Ok(_) => println!("successfully wrote to {}", display),
3635
}
3736
}
@@ -40,10 +39,9 @@ fn main() {
4039
Here's the expected successful output:
4140

4241
```shell
43-
$ mkdir out
4442
$ rustc create.rs && ./create
45-
successfully wrote to out/lorem_ipsum.txt
46-
$ cat out/lorem_ipsum.txt
43+
successfully wrote to lorem_ipsum.txt
44+
$ cat lorem_ipsum.txt
4745
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
4846
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
4947
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo

src/std_misc/file/open.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ A `File` owns a resource, the file descriptor and takes care of closing the
66
file when it is `drop`ed.
77

88
```rust,editable,ignore
9-
use std::error::Error;
109
use std::fs::File;
1110
use std::io::prelude::*;
1211
use std::path::Path;
@@ -18,24 +17,19 @@ fn main() {
1817
1918
// Open the path in read-only mode, returns `io::Result<File>`
2019
let mut file = match File::open(&path) {
21-
// The `description` method of `io::Error` returns a string that
22-
// describes the error
23-
Err(why) => panic!("couldn't open {}: {}", display,
24-
why.description()),
20+
Err(why) => panic!("couldn't open {}: {}", display, why),
2521
Ok(file) => file,
2622
};
2723
2824
// Read the file contents into a string, returns `io::Result<usize>`
2925
let mut s = String::new();
3026
match file.read_to_string(&mut s) {
31-
Err(why) => panic!("couldn't read {}: {}", display,
32-
why.description()),
27+
Err(why) => panic!("couldn't read {}: {}", display, why),
3328
Ok(_) => print!("{} contains:\n{}", display, s),
3429
}
3530
3631
// `file` goes out of scope, and the "hello.txt" file gets closed
3732
}
38-
3933
```
4034

4135
Here's the expected successful output:

src/std_misc/process/pipe.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ The `std::Child` struct represents a running child process, and exposes the
55
process via pipes.
66

77
```rust,ignore
8-
use std::error::Error;
98
use std::io::prelude::*;
109
use std::process::{Command, Stdio};
1110
@@ -18,7 +17,7 @@ fn main() {
1817
.stdin(Stdio::piped())
1918
.stdout(Stdio::piped())
2019
.spawn() {
21-
Err(why) => panic!("couldn't spawn wc: {}", why.description()),
20+
Err(why) => panic!("couldn't spawn wc: {}", why),
2221
Ok(process) => process,
2322
};
2423
@@ -27,8 +26,7 @@ fn main() {
2726
// `stdin` has type `Option<ChildStdin>`, but since we know this instance
2827
// must have one, we can directly `unwrap` it.
2928
match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
30-
Err(why) => panic!("couldn't write to wc stdin: {}",
31-
why.description()),
29+
Err(why) => panic!("couldn't write to wc stdin: {}", why),
3230
Ok(_) => println!("sent pangram to wc"),
3331
}
3432
@@ -41,8 +39,7 @@ fn main() {
4139
// The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
4240
let mut s = String::new();
4341
match process.stdout.unwrap().read_to_string(&mut s) {
44-
Err(why) => panic!("couldn't read wc stdout: {}",
45-
why.description()),
42+
Err(why) => panic!("couldn't read wc stdout: {}", why),
4643
Ok(_) => print!("wc responded with:\n{}", s),
4744
}
4845
}

0 commit comments

Comments
 (0)