diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2017-08-14 19:36:13 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2017-08-14 19:36:13 -0700 |
| commit | 1413253a41de87ce7da73f0733aa3f433b1f5a3b (patch) | |
| tree | 111cba46a53aaaa0733b6b8ba19aece25b6f8533 /src/doc | |
| parent | b045c201b2086073f43d76290b9cb2a5a8e16f89 (diff) | |
| parent | 56fe3b2ad0055bb28325f412395577e2b842719a (diff) | |
| download | rust-1413253a41de87ce7da73f0733aa3f433b1f5a3b.tar.gz rust-1413253a41de87ce7da73f0733aa3f433b1f5a3b.zip | |
Merge remote-tracking branch 'origin/master' into gen
Diffstat (limited to 'src/doc')
| -rw-r--r-- | src/doc/rustdoc/src/SUMMARY.md | 2 | ||||
| -rw-r--r-- | src/doc/rustdoc/src/documentation-tests.md | 238 | ||||
| -rw-r--r-- | src/doc/rustdoc/src/in-source-directives.md | 3 | ||||
| -rw-r--r-- | src/doc/rustdoc/src/the-doc-attribute.md | 178 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/language-features/doc-cfg.md | 42 |
5 files changed, 458 insertions, 5 deletions
diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md index cd6883a719c..1049cc4284a 100644 --- a/src/doc/rustdoc/src/SUMMARY.md +++ b/src/doc/rustdoc/src/SUMMARY.md @@ -2,7 +2,7 @@ - [What is rustdoc?](what-is-rustdoc.md) - [Command-line arguments](command-line-arguments.md) -- [In-source directives](in-source-directives.md) +- [The `#[doc]` attribute](the-doc-attribute.md) - [Documentation tests](documentation-tests.md) - [Plugins](plugins.md) - [Passes](passes.md) \ No newline at end of file diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index cd7d657e116..4f7736d8df6 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -1,3 +1,239 @@ # Documentation tests -Coming soon! \ No newline at end of file +`rustdoc` supports executing your documentation examples as tests. This makes sure +that your tests are up to date and working. + +The basic idea is this: + +```rust,ignore +/// # Examples +/// +/// ``` +/// let x = 5; +/// ``` +``` + +The triple backticks start and end code blocks. If this were in a file named `foo.rs`, +running `rustdoc --test foo.rs` will extract this example, and then run it as a test. + +There's some subtlety though! Read on for more details. + +## Pre-processing examples + +In the example above, you'll note something strange: there's no `main` +function! Forcing you to write `main` for every example, no matter how small, +adds friction. So `rustdoc` processes your examples slightly before +running them. Here's the full algorithm rustdoc uses to preprocess examples: + +1. Any leading `#![foo]` attributes are left intact as crate attributes. +2. Some common `allow` attributes are inserted, including + `unused_variables`, `unused_assignments`, `unused_mut`, + `unused_attributes`, and `dead_code`. Small examples often trigger + these lints. +3. If the example does not contain `extern crate`, then `extern crate + <mycrate>;` is inserted (note the lack of `#[macro_use]`). +4. Finally, if the example does not contain `fn main`, the remainder of the + text is wrapped in `fn main() { your_code }`. + +For more about that caveat in rule 3, see "Documeting Macros" below. + +## Hiding portions of the example + +Sometimes, you need some setup code, or other things that would distract +from your example, but are important to make the tests work. Consider +an example block that looks like this: + +```text +/// Some documentation. +# fn foo() {} +``` + +It will render like this: + +```rust +/// Some documentation. +# fn foo() {} +``` + +Yes, that's right: you can add lines that start with `# `, and they will +be hidden from the output, but will be used when compiling your code. You +can use this to your advantage. In this case, documentation comments need +to apply to some kind of function, so if I want to show you just a +documentation comment, I need to add a little function definition below +it. At the same time, it's only there to satisfy the compiler, so hiding +it makes the example more clear. You can use this technique to explain +longer examples in detail, while still preserving the testability of your +documentation. + +For example, imagine that we wanted to document this code: + +```rust +let x = 5; +let y = 6; +println!("{}", x + y); +``` + +We might want the documentation to end up looking like this: + +> First, we set `x` to five: +> +> ```rust +> let x = 5; +> # let y = 6; +> # println!("{}", x + y); +> ``` +> +> Next, we set `y` to six: +> +> ```rust +> # let x = 5; +> let y = 6; +> # println!("{}", x + y); +> ``` +> +> Finally, we print the sum of `x` and `y`: +> +> ```rust +> # let x = 5; +> # let y = 6; +> println!("{}", x + y); +> ``` + +To keep each code block testable, we want the whole program in each block, but +we don't want the reader to see every line every time. Here's what we put in +our source code: + +```text + First, we set `x` to five: + + ```rust + let x = 5; + # let y = 6; + # println!("{}", x + y); + ``` + + Next, we set `y` to six: + + ```rust + # let x = 5; + let y = 6; + # println!("{}", x + y); + ``` + + Finally, we print the sum of `x` and `y`: + + ```rust + # let x = 5; + # let y = 6; + println!("{}", x + y); + ``` +``` + +By repeating all parts of the example, you can ensure that your example still +compiles, while only showing the parts that are relevant to that part of your +explanation. + +Another case where the use of `#` is handy is when you want to ignore +error handling. Lets say you want the following, + +```rust,ignore +/// use std::io; +/// let mut input = String::new(); +/// io::stdin().read_line(&mut input)?; +``` + +The problem is that `?` returns a `Result<T, E>` and test functions +don't return anything so this will give a mismatched types error. + +```rust,ignore +/// A doc test using ? +/// +/// ``` +/// use std::io; +/// # fn foo() -> io::Result<()> { +/// let mut input = String::new(); +/// io::stdin().read_line(&mut input)?; +/// # Ok(()) +/// # } +/// ``` +# fn foo() {} +``` + +You can get around this by wrapping the code in a function. This catches +and swallows the `Result<T, E>` when running tests on the docs. This +pattern appears regularly in the standard library. + +### Documenting macros + +Here’s an example of documenting a macro: + +```rust +/// Panic with a given message unless an expression evaluates to true. +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate foo; +/// # fn main() { +/// panic_unless!(1 + 1 == 2, “Math is broken.”); +/// # } +/// ``` +/// +/// ```rust,should_panic +/// # #[macro_use] extern crate foo; +/// # fn main() { +/// panic_unless!(true == false, “I’m broken.”); +/// # } +/// ``` +#[macro_export] +macro_rules! panic_unless { + ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } }); +} +# fn main() {} +``` + +You’ll note three things: we need to add our own `extern crate` line, so that +we can add the `#[macro_use]` attribute. Second, we’ll need to add our own +`main()` as well (for reasons discussed above). Finally, a judicious use of +`#` to comment out those two things, so they don’t show up in the output. + +## Attributes + +There are a few annotations that are useful to help `rustdoc` do the right +thing when testing your code: + +```rust +/// ```ignore +/// fn foo() { +/// ``` +# fn foo() {} +``` + +The `ignore` directive tells Rust to ignore your code. This is almost never +what you want, as it's the most generic. Instead, consider annotating it +with `text` if it's not code, or using `#`s to get a working example that +only shows the part you care about. + +```rust +/// ```should_panic +/// assert!(false); +/// ``` +# fn foo() {} +``` + +`should_panic` tells `rustdoc` that the code should compile correctly, but +not actually pass as a test. + +```rust +/// ```no_run +/// loop { +/// println!("Hello, world"); +/// } +/// ``` +# fn foo() {} +``` + +The `no_run` attribute will compile your code, but not run it. This is +important for examples such as "Here's how to retrieve a web page," +which you would want to ensure compiles, but might be run in a test +environment that has no network access. \ No newline at end of file diff --git a/src/doc/rustdoc/src/in-source-directives.md b/src/doc/rustdoc/src/in-source-directives.md deleted file mode 100644 index 83f677fa7f4..00000000000 --- a/src/doc/rustdoc/src/in-source-directives.md +++ /dev/null @@ -1,3 +0,0 @@ -# In-source directives - -Coming soon! \ No newline at end of file diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md new file mode 100644 index 00000000000..978d7656bdd --- /dev/null +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -0,0 +1,178 @@ +# The `#[doc]` attribute + +The `#[doc]` attribute lets you control various aspects of how `rustdoc` does +its job. + +The most basic function of `#[doc]` is to handle the actual documentation +text. That is, `///` is syntax sugar for `#[doc]`. This means that these two +are the same: + +```rust,ignore +/// This is a doc comment. +#[doc = " This is a doc comment."] +``` + +(Note the leading space in the attribute version.) + +In most cases, `///` is easier to use than `#[doc]`. One case where the latter is easier is +when generating documentation in macros; the `collapse-docs` pass will combine multiple +`#[doc]` attributes into a single doc comment, letting you generate code like this: + +```rust,ignore +#[doc = "This is"] +#[doc = " a "] +#[doc = "doc comment"] +``` + +Which can feel more flexible. Note that this would generate this: + +```rust,ignore +#[doc = "This is\n a \ndoc comment"] +``` + +but given that docs are rendered via Markdown, it will remove these newlines. + +The `doc` attribute has more options though! These don't involve the text of +the output, but instead, various aspects of the presentation of the output. +We've split them into two kinds below: attributes that are useful at the +crate level, and ones that are useful at the item level. + +## At the crate level + +These options control how the docs look at a macro level. + +### `html_favicon_url` + +This form of the `doc` attribute lets you control the favicon of your docs. + +```rust,ignore +#![doc(html_favicon_url = "https://example.com/favicon.ico")] +``` + +This will put `<link rel="shortcut icon" href="{}">` into your docs, where +the string for the attribute goes into the `{}`. + +If you don't use this attribute, there will be no favicon. + +### `html_logo_url` + +This form of the `doc` attribute lets you control the logo in the upper +left hand side of the docs. + +```rust,ignore +#![doc(html_logo_url = "https://example.com/logo.jpg")] +``` + +This will put `<a href='index.html'><img src='{}' alt='logo' width='100'></a>` into +your docs, where the string for the attribute goes into the `{}`. + +If you don't use this attribute, there will be no logo. + +### `html_playground_url` + +This form of the `doc` attribute lets you control where the "run" buttons +on your documentation examples make requests to. + +```rust,ignore +#![doc(html_playground_url = "https://playground.example.com/")] +``` + +Now, when you press "run", the button will make a request to this domain. + +If you don't use this attribute, there will be no run buttons. + +### `issue_tracker_base_url` + +This form of the `doc` attribute is mostly only useful for the standard library; +When a feature is unstable, an issue number for tracking the feature must be +given. `rustdoc` uses this number, plus the base URL given here, to link to +the tracking issue. + +```rust,ignore +#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] +``` + +### `html_no_source` + +By default, `rustdoc` will include the source code of your program, with links +to it in the docs. But if you include this: + +```rust,ignore +#![doc(html_no_source)] +``` + +it will not. + +## At the item level + +These forms of the `#[doc]` attribute are used on individual items, to control how +they are documented. + +## `#[doc(no_inline)]`/`#[doc(inline)]` + +These attributes are used on `use` statements, and control where the documentation shows +up. For example, consider this Rust code: + +```rust,ignore +pub use bar::Bar; + +/// bar docs +pub mod bar { + /// the docs for Bar + pub struct Bar; +} +``` + +The documentation will generate a "Reexports" section, and say `pub use bar::Bar;`, where +`Bar` is a link to its page. + +If we change the `use` line like this: + +```rust,ignore +#[doc(inline)] +pub use bar::Bar; +``` + +Instead, `Bar` will appear in a `Structs` section, just like `Bar` was defined at the +top level, rather than `pub use`'d. + +Let's change our original example, by making `bar` private: + +```rust,ignore +pub use bar::Bar; + +/// bar docs +mod bar { + /// the docs for Bar + pub struct Bar; +} +``` + +Here, because `bar` is not public, `Bar` wouldn't have its own page, so there's nowhere +to link to. `rustdoc` will inline these definitions, and so we end up in the same case +as the `#[doc(inline)]` above; `Bar` is in a `Structs` section, as if it were defined at +the top level. If we add the `no_inline` form of the attribute: + +```rust,ignore +#[doc(no_inline)] +pub use bar::Bar; + +/// bar docs +mod bar { + /// the docs for Bar + pub struct Bar; +} +``` + +Now we'll have a `Reexports` line, and `Bar` will not link to anywhere. + +## `#[doc(hidden)]` + +Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless +the `strip-hidden` pass is removed. + +## `#[doc(primitive)]` + +Since primitive types are defined in the compiler, there's no place to attach documentation +attributes. This attribute is used by the standard library to provide a way to generate +documentation for primitive types. diff --git a/src/doc/unstable-book/src/language-features/doc-cfg.md b/src/doc/unstable-book/src/language-features/doc-cfg.md new file mode 100644 index 00000000000..ddc538e1214 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/doc-cfg.md @@ -0,0 +1,42 @@ +# `doc_cfg` + +The tracking issue for this feature is: [#43781] + +------ + +The `doc_cfg` feature allows an API be documented as only available in some specific platforms. +This attribute has two effects: + +1. In the annotated item's documentation, there will be a message saying "This is supported on + (platform) only". + +2. The item's doc-tests will only run on the specific platform. + +This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the +standard library be documented. + +```rust +#![feature(doc_cfg)] + +#[cfg(any(windows, feature = "documentation"))] +#[doc(cfg(windows))] +/// The application's icon in the notification area (a.k.a. system tray). +/// +/// # Examples +/// +/// ```no_run +/// extern crate my_awesome_ui_library; +/// use my_awesome_ui_library::current_app; +/// use my_awesome_ui_library::windows::notification; +/// +/// let icon = current_app().get::<notification::Icon>(); +/// icon.show(); +/// icon.show_message("Hello"); +/// ``` +pub struct Icon { + // ... +} +``` + +[#43781]: https://github.com/rust-lang/rust/issues/43781 +[#43348]: https://github.com/rust-lang/rust/issues/43348 \ No newline at end of file |
