Skip to content

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

Open
@teymour-aldridge

Description

@teymour-aldridge

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions