an example block that looks like this:
```text
-/// Some documentation.
-# fn foo() {}
+/// /// Some documentation.
+/// # fn foo() {} // this function will be hidden
+/// println!("Hello, World!");
```
It will render like this:
```rust
/// Some documentation.
# fn foo() {}
+println!("Hello, World!");
```
Yes, that's right: you can add lines that start with `# `, and they will
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,
+
+## Using `?` in doc tests
+
+When writing an example, it is rarely useful to include a complete error
+handling, as it would add significant amounts of boilerplate code. Instead, you
+may want the following:
```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.
+The problem is that `?` returns a `Result<T, E>` and test functions don't
+return anything, so this will give a mismatched types error.
+
+You can get around this limitation by manually adding a `main` that returns
+`Result<T, E>`, because `Result<T, E>` implements the `Termination` trait:
```ignore
/// A doc test using ?
///
/// ```
/// use std::io;
-/// # fn foo() -> io::Result<()> {
+///
+/// fn main() -> io::Result<()> {
+/// let mut input = String::new();
+/// io::stdin().read_line(&mut input)?;
+/// Ok(())
+/// }
+/// ```
+```
+
+Together with the `# ` from the section above, you arrive at a solution that
+appears to the reader as the initial idea but works with doc tests:
+
+```ignore
+/// ```
+/// use std::io;
+/// # fn main() -> 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
+## Documenting macros
Here’s an example of documenting a macro:
) -> Option<Const<'tcx>> {
let span = source_info.span;
match *rvalue {
- // No need to overwrite an already evaluated constant
- Rvalue::Use(Operand::Constant(box Constant {
- literal: Literal::Value {
- value: &ty::Const {
- val: ConstVal::Value(_),
- ..
- },
- },
- ..
- })) => None,
// This branch exists for the sanity type check
Rvalue::Use(Operand::Constant(ref c)) => {
assert_eq!(c.ty, place_ty);
let krate = panictry!(driver::phase_1_parse_input(control, &sess, &input));
- let name = ::rustc_codegen_utils::link::find_crate_name(Some(&sess), &krate.attrs, &input);
+ let name = match crate_name {
+ Some(ref crate_name) => crate_name.clone(),
+ None => ::rustc_codegen_utils::link::find_crate_name(Some(&sess), &krate.attrs, &input),
+ };
let mut crate_loader = CrateLoader::new(&sess, &cstore, &name);
pub fn sub_instant(&self, other: &Instant) -> Duration {
self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
- panic!("other was less than the current instant")
+ panic!("specified instant was later than self")
})
}
pub fn sub_instant(&self, other: &Instant) -> Duration {
self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
- panic!("other was less than the current instant")
+ panic!("specified instant was later than self")
})
}
// ignore-powerpc64
// ignore-s390x
// ignore-sparc
+// ignore-sparc64
// ignore-wasm32
// ignore-x86
// ignore-x86_64
// ignore-r600
// ignore-amdgcn
// ignore-sparc
+// ignore-sparc64
// ignore-sparcv9
// ignore-sparcel
// ignore-s390x
// ignore-asmjs
// ignore-mips64
// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
// ignore-wasm
// ignore-x86
// ignore-x86_64
// ignore-mips64
// ignore-powerpc
// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
// ignore-wasm
// ignore-emscripten
// ignore-windows
// ignore-emscripten
// ignore-mips
// ignore-mips64
+// ignore-sparc
+// ignore-sparc64
// compile-flags: -O
#![feature(repr_simd)]
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
// ignore-mips64
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
// ignore-mips64
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
// ignore-mips64
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
// ignore-mips64
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
// ignore-mips64
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
//~^ ERROR this constant cannot be used
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
//~^ ERROR this constant cannot be used
-pub const E: u8 = [5u8][1];
-//~^ ERROR const_err
+pub const E: u8 = [5u8][1]; //~ ERROR const_err
+//~| ERROR this constant cannot be used
fn main() {
let _a = A;
let d = 42u8 - (42u8 + 1);
//~^ ERROR const_err
let _e = [5u8][1];
+ //~^ ERROR const_err
black_box(a);
black_box(b);
black_box(c);
let d = 42u8 - (42u8 + 1);
//~^ ERROR const_err
let _e = [5u8][1];
+ //~^ ERROR const_err
black_box(b);
black_box(c);
black_box(d);
const C: [u32; 5] = [0; 5];
+#[allow(const_err)]
fn test() -> u32 {
C[10]
}
const C: &'static [u8; 5] = b"hello";
+#[allow(const_err)]
fn test() -> u8 {
C[10]
}
const C: &'static [u8; 5] = b"hello";
+#[allow(const_err)]
fn mir() -> u8 {
C[10]
}
--- /dev/null
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test case from #39963.
+
+#![feature(nll)]
+
+#[derive(Clone)]
+struct Foo(Option<Box<Foo>>, Option<Box<Foo>>);
+
+fn test(f: &mut Foo) {
+ match *f {
+ Foo(Some(ref mut left), Some(ref mut right)) => match **left {
+ Foo(Some(ref mut left), Some(ref mut right)) => panic!(),
+ _ => panic!(),
+ },
+ _ => panic!(),
+ }
+}
+
+fn main() {
+}
// ignore-mips64
// ignore-powerpc
// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
// ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes
// ignore-mips64
// ignore-powerpc
// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
// ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes
--- /dev/null
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --crate-name foo
+
+pub fn foo() {}
// ignore-emscripten
// ignore-powerpc
// ignore-sparc
+// ignore-sparc64
// ignore-mips
#![feature(asm)]
error[E0384]: cannot assign twice to immutable variable `x`
- --> $DIR/asm-out-assign-imm.rs:30:9
+ --> $DIR/asm-out-assign-imm.rs:31:9
|
LL | x = 1;
| ----- first assignment to `x`
+++ /dev/null
-// Copyright 2018 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static FOO: i32 = [][0];
-//~^ ERROR E0080
-
-fn main() {}
+++ /dev/null
-error[E0080]: constant evaluation error
- --> $DIR/index_out_of_bound.rs:11:19
- |
-LL | static FOO: i32 = [][0];
- | ^^^^^ index out of bounds: the len is 0 but the index is 0
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0080`.
--- /dev/null
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static FOO: i32 = [][0];
+//~^ ERROR E0080
+
+fn main() {
+ let array = [std::env::args().len()];
+ array[1]; //~ ERROR index out of bounds
+}
--- /dev/null
+error[E0080]: constant evaluation error
+ --> $DIR/index_out_of_bounds.rs:11:19
+ |
+LL | static FOO: i32 = [][0];
+ | ^^^^^ index out of bounds: the len is 0 but the index is 0
+
+error: index out of bounds: the len is 1 but the index is 1
+ --> $DIR/index_out_of_bounds.rs:16:5
+ |
+LL | array[1]; //~ ERROR index out of bounds
+ | ^^^^^^^^
+ |
+ = note: #[deny(const_err)] on by default
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
// ignore-mips
// ignore-powerpc
// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
#![feature(target_feature)]
error: #[target_feature] attribute must be of the form #[target_feature(..)]
- --> $DIR/target-feature-wrong.rs:21:1
+ --> $DIR/target-feature-wrong.rs:23:1
|
LL | #[target_feature = "+sse2"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the feature named `foo` is not valid for this target
- --> $DIR/target-feature-wrong.rs:23:18
+ --> $DIR/target-feature-wrong.rs:25:18
|
LL | #[target_feature(enable = "foo")]
| ^^^^^^^^^^^^^^
error: #[target_feature(..)] only accepts sub-keys of `enable` currently
- --> $DIR/target-feature-wrong.rs:25:18
+ --> $DIR/target-feature-wrong.rs:27:18
|
LL | #[target_feature(bar)]
| ^^^
error: #[target_feature(..)] only accepts sub-keys of `enable` currently
- --> $DIR/target-feature-wrong.rs:27:18
+ --> $DIR/target-feature-wrong.rs:29:18
|
LL | #[target_feature(disable = "baz")]
| ^^^^^^^^^^^^^^^
error: #[target_feature(..)] can only be applied to `unsafe` function
- --> $DIR/target-feature-wrong.rs:31:1
+ --> $DIR/target-feature-wrong.rs:33:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: attribute should be applied to a function
- --> $DIR/target-feature-wrong.rs:35:1
+ --> $DIR/target-feature-wrong.rs:37:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| -------------- not a function
error: cannot use #[inline(always)] with #[target_feature]
- --> $DIR/target-feature-wrong.rs:39:1
+ --> $DIR/target-feature-wrong.rs:41:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^