Skip to content

"introduce a type parameter with a trait bound instead of using impl Trait" diagnostic is malformed for async fns where the previous parameter is a borrow #79843

Closed
@Arnavion

Description

@Arnavion

(Edit: Actually, being an inherent fn doesn't matter. It happens with top-level fns too.)

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=bc52a6f5c708462abbd91b4dd7d9b1ba

trait Foo {
    type Bar;
    fn bar(&self) -> Self::Bar;
}

async fn run(_: &(), foo: impl Foo) -> std::io::Result<()> {
    fn assert_is_send<T: Send>(_: &T) {}

    let bar = foo.bar();
    assert_is_send(&bar);

    Ok(())
}

This prints the diagnostic:

error[E0277]: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
  --> src/lib.rs:10:20
   |
7  |     fn assert_is_send<T: Send>(_: &T) {}
   |                          ---- required by this bound in `assert_is_send`
...
10 |     assert_is_send(&bar);
   |                    ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
   |
   = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
help: introduce a type parameter with a trait bound instead of using `impl Trait`
   |
6  | async fn run(_: &, F: Foo(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send {
   |                  ^^^^^^^^         ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

The suggestion in the last line is not valid syntax (_: &,). It also emits malformed syntax if the first parameter is a &self or &mut self parameter.

The diagnostic becomes well-formed if any of the following is done:

  • The first parameter is changed to _: () instead of _: &()

  • The fn is not an async fn.

In either case, the diagnostic correctly says:

6  | fn run<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send {
   |       ^^^^^^^^              ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Meta

Happens on both nightly:

rustc 1.50.0-nightly (e792288df 2020-12-05)
binary: rustc
commit-hash: e792288df31636ca28108516c63a00ce4267063a
commit-date: 2020-12-05
host: x86_64-unknown-linux-gnu
release: 1.50.0-nightly

... and stable:

rustc 1.48.0 (7eac88abb 2020-11-16)
binary: rustc
commit-hash: 7eac88abb2e57e752f3302f02be5f3ce3d7adfb4
commit-date: 2020-11-16
host: x86_64-unknown-linux-gnu
release: 1.48.0
LLVM version: 11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.E-help-wantedCall for participation: Help is requested to fix this issue.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions