Repository: rust
Issue: Error messages confusing trying to return errors across threads
Labels: C-enhancement,A-diagnostics,T-compiler,D-confusing,D-newcomer-roadblock

Compiling:

```rust
fn main() -> Result<(), Box<dyn std::error::Error>> 
{
    std::thread::spawn(|| -> Result<(), Box<dyn std::error::Error>> {
        Ok(()) 
    });
    Ok(())
}
```

Gives:

```
   Compiling playground v0.0.1 (/playground)
error[E0277]: `dyn std::error::Error` cannot be sent between threads safely
   --> src/main.rs:5:5
    |
5   |     std::thread::spawn(|| -> Result<(), Box<dyn std::error::Error>> {
    |     ^^^^^^^^^^^^^^^^^^ `dyn std::error::Error` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn std::error::Error`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn std::error::Error>`
    = note: required because it appears within the type `std::boxed::Box<dyn std::error::Error>`
    = note: required because it appears within the type `std::result::Result<(), std::boxed::Box<dyn std::error::Error>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
```

Since this is the frequently suggested idiom for being able to return any kind of error, it can be surprising to users that it doesn't seem to work for threads other than the main thread. It could suggest adding Send, and then users can quickly run into another problem:

```rust
fn fallible() -> Result<(), std::io::Error> 
{
    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> 
{
    std::thread::spawn(|| -> Result<(), Box<dyn std::error::Error + Send>> {
        fallible()?;
        Ok(())
    });
    Ok(())
}
```

Where they will get the error:

```
   Compiling playground v0.0.1 (/playground)
error[E0277]: `?` couldn't convert the error to `std::boxed::Box<dyn std::error::Error + std::marker::Send>`
 --> src/main.rs:9:19
  |
9 |         fallible()?;
  |                   ^ the trait `std::convert::From<std::io::Error>` is not implemented for `std::boxed::Box<dyn std::error::Error + std::marker::Send>`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  = help: the following implementations were found:
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::borrow::Cow<'a, str>>>
            <std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::string::String>>
          and 22 others
  = note: required by `std::convert::From::from`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
```

Which is confusing even for people who know about Send, because intuitively we should be able to convert from something with more requirements to something with less requirements.