Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error messages confusing trying to return errors across threads #75001

Open
jgarvin opened this issue Aug 1, 2020 · 0 comments
Open

Error messages confusing trying to return errors across threads #75001

jgarvin opened this issue Aug 1, 2020 · 0 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jgarvin
Copy link

jgarvin commented Aug 1, 2020

Compiling:

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:

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.

@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 1, 2020
@JohnTitor JohnTitor added D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels Aug 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants