Skip to content

Better error messages for sending format! uses across thread boundaries. #82696

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

Open
teymour-aldridge opened this issue Mar 2, 2021 · 0 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@teymour-aldridge
Copy link
Contributor

Given the following code:

fn main() {
    let format = format_args!("{}", 1);
    std::thread::spawn(move || {
        format;
    })
    .join()
    .unwrap();
}

The current output is:

   Compiling playground v0.0.1 (/playground)
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
   --> src/main.rs:3:5
    |
3   |     std::thread::spawn(move || {
    |     ^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
    |
    = help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque`
    = note: required because it appears within the type `&core::fmt::Opaque`
    = note: required because it appears within the type `ArgumentV1<'_>`
    = note: required because it appears within the type `[ArgumentV1<'_>]`
    = note: required because of the requirements on the impl of `Send` for `&[ArgumentV1<'_>]`
    = note: required because it appears within the type `Arguments<'_>`
    = note: required because it appears within the type `[closure@src/main.rs:3:24: 5:6]`

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.

Ideally the output should look like: I think it would be more helpful to point out which variable is being across a thread boundary. So something like,

fn main() {
    let format = format_args!("{}", 1);
         ^^^ format is of type `core::fmt::Opaque` which is not `Sync`
    std::thread::spawn(move || {
                                   ^^^ `format` is moved into this closure here, but in order to do so it must be `Sync` because it is being sent accross a thread boundary
        format;
    })
    .join()
    .unwrap();
}

I think it would also be helpful to point out that ArgumentV1<'_> comes from a format! invocation because it is not immediately obvious. I did run into this bug a few weeks ago, and I was only able to work this out after an internet search result returned some of rustc's tests.

@teymour-aldridge teymour-aldridge added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 2, 2021
@fmease fmease added the D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. label Feb 11, 2025
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 D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. 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

2 participants