Repository: rust
Issue: Clearer error for failed tests which returned a Result Err()
Labels: C-enhancement,T-compiler,A-libtest

<!-- Thanks for filing a 🐛 bug report 😄! -->

**Problem**
I have a test function which returns a `Result<...>` as a convenient way of testing failable methods. For example:

```rust
#[test]
fn exampletest() -> Result<(), std::io::Error> {
    let f = std::fs::File::open("/root/nonexistantfile")?;
    assert_eq!(example_method(&f), 0);
    Ok(())
}
```

The test started failing for whatever reason, and the `cargo test` output looked like this:

```
$ cargo test
   Compiling confusing v0.1.0 (/Users/dbr/confusing)
    Finished test [unoptimized + debuginfo] target(s) in 0.42s
     Running target/debug/deps/confusing-3ccdc020a15819b0

running 1 test
test exampletest ... FAILED

failures:

---- exampletest stdout ----
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
thread 'exampletest' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: the test returned a termination value with a non-zero status code (1) which indicates a failure', src/libtest/lib.rs:196:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    exampletest

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--bin confusing'
```

Not reading the output properly, I interpreted the `panicked at 'assertion failed: ...` as being a failure from my `assert_eq!` and started trying to work out why my `example_method` was returning 0.

I also tried running the tests under a debugger, but the backtrace only pointed at the test closure rather than the probelmatic line:

```
...
  13: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:328
  14: test::assert_test_result
             at ./<::std::macros::panic macros>:9
  15: confusing::exampletest::{{closure}}
             at src/main.rs:6
  16: core::ops::function::FnOnce::call_once
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ops/function.rs:227
```
..where src/main.rs:6 is the line `fn exampletest() -> Result<(), std::io::Error> {`

**Steps**
<!-- The steps to reproduce the bug. -->
1. Write a test case returning a `Result<...>`
2. Have the test case fail by returning `Err(...)`
3. Misread the output!

**Possible Solution(s)**
I think there are two aspects to this:

First is the panic message from the assert is talking about "internal" details - the exit code of the test. The fact the test (I assume) runs as a process and the exit-code is used to determine failure isn't something I was thinking about while writing/debugging the test.

For this, I think it would help a lot to just simplify the panic message from saying
```
thread 'exampletest' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: the test returned a termination value with a non-zero status code (1) which indicates a failure', src/libtest/lib.rs:196:5
```
to something more concise like:
```
thread 'exampletest' panicked at 'the test exited with non-zero exit code (1) which indicates a failure', src/libtest/lib.rs:196:5
```

Second part I'm not so clear about, but it seems like the Result isn't being handled specially - the `Err` is just being turned into an exit code, then asserted later. Since the panic comes from this assertion, the backtrace doesn't reference the actual line which failed.

This is different to if I had, say, used `.unwrap()` instead of `?`:

```
...
  16: core::result::Result<T,E>::unwrap
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/result.rs:933
  17: confusing::exampletest
             at src/main.rs:7
  18: confusing::exampletest::{{closure}}
             at src/main.rs:6
  19: core::ops::function::FnOnce::call_once
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ops/function.rs:227
...
```

where line 7 is the problem-causing line `let _f = std::fs::File::open("/root/nonexistantfile").unwrap();` - it would be nice if using `?` resulted in a similar traceback

**Notes**

Output of `cargo version`:

```$ cargo version
cargo 1.40.0 (bc8e4c8be 2019-11-22)
```
```
$ rustup show
Default host: x86_64-apple-darwin
rustup home:  /Users/dbr/.rustup

installed toolchains
--------------------

stable-x86_64-apple-darwin
nightly-x86_64-apple-darwin

installed targets for active toolchain
--------------------------------------

arm-unknown-linux-musleabihf
wasm32-unknown-unknown
x86_64-apple-darwin

active toolchain
----------------

stable-x86_64-apple-darwin (default)
rustc 1.40.0 (73528e339 2019-12-16)
```