Skip to content

Commit

Permalink
Rollup merge of rust-lang#56470 - llogiq:process-termination-doctest,…
Browse files Browse the repository at this point in the history
… r=GuillaumeGomez

Modify doctest's auto-`fn main()` to allow `Result`s

This lets the default `fn main()` ~~return `impl Termination`~~ unwrap Results, which allows the use of `?` in most tests without adding it manually. This fixes rust-lang#56260

~~Blocked on `std::process::Termination` stabilization.~~

Using `Termination` would have been cleaner, but this should work OK.
  • Loading branch information
GuillaumeGomez committed Feb 17, 2019
2 parents 9a3392e + dad211e commit e91ec2b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
17 changes: 17 additions & 0 deletions src/doc/rustdoc/src/documentation-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,23 @@ appears to the reader as the initial idea but works with doc tests:
/// ```
```
As of version 1.34.0, one can also omit the `fn main()`, but you will have to
disambiguate the error type:
```ignore
/// ```
/// use std::io;
/// let mut input = String::new();
/// io::stdin().read_line(&mut input)?;
/// # Ok::<(), io:Error>(())
/// ```
```
This is an unfortunate consequence of the `?` operator adding an implicit
conversion, so type inference fails because the type is not unique. Please note
that you must write the `(())` in one sequence without intermediate whitespace
so that rustdoc understands you want an implicit `Result`-returning function.
## Documenting macros
Here’s an example of documenting a macro:
Expand Down
14 changes: 10 additions & 4 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,13 +534,19 @@ pub fn make_test(s: &str,
}
}

if dont_insert_main || already_has_main {
// FIXME: This code cannot yet handle no_std test cases yet
if dont_insert_main || already_has_main || prog.contains("![no_std]") {
prog.push_str(everything_else);
} else {
prog.push_str("fn main() {\n");
let returns_result = everything_else.trim_end().ends_with("(())");
let (main_pre, main_post) = if returns_result {
("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
"}\n_inner().unwrap() }")
} else {
("fn main() {\n", "\n}")
};
prog.extend([main_pre, everything_else, main_post].iter().cloned());
line_offset += 1;
prog.push_str(everything_else);
prog.push_str("\n}");
}

debug!("final doctest:\n{}", prog);
Expand Down
24 changes: 24 additions & 0 deletions src/test/rustdoc/process-termination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// compile-flags:--test

/// A check of using various process termination strategies
///
/// # Examples
///
/// ```rust
/// assert!(true); // this returns `()`, all is well
/// ```
///
/// You can also simply return `Ok(())`, but you'll need to disambiguate the
/// type using turbofish, because we cannot infer the type:
///
/// ```rust
/// Ok::<(), &'static str>(())
/// ```
///
/// You can err with anything that implements `Debug`:
///
/// ```rust,should_panic
/// Err("This is returned from `main`, leading to panic")?;
/// Ok::<(), &'static str>(())
/// ```
pub fn check_process_termination() {}

0 comments on commit e91ec2b

Please sign in to comment.