Skip to content

E0277 incorrect suggested where bound when type is impl Trait argument #86488

Open
@delan

Description

@delan

Given the following code (playground):

trait Foo: Copy {
    type Result;
    fn foo(self) -> Self::Result;
}

fn bar(foo: impl Foo) {
    let _: () = foo.into();
    let _: () = foo.foo().into();
}

The current output is:

error[E0277]: the trait bound `(): From<impl Foo>` is not satisfied
 --> src/lib.rs:7:21
  |
7 |     let _: () = foo.into();
  |                     ^^^^ the trait `From<impl Foo>` is not implemented for `()`
  |
  = note: required because of the requirements on the impl of `Into<()>` for `impl Foo`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar(foo: impl Foo) where (): From<impl Foo> {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `(): From<<impl Foo as Foo>::Result>` is not satisfied
 --> src/lib.rs:8:27
  |
8 |     let _: () = foo.foo().into();
  |                           ^^^^ the trait `From<<impl Foo as Foo>::Result>` is not implemented for `()`
  |
  = note: required because of the requirements on the impl of `Into<()>` for `<impl Foo as Foo>::Result`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar(foo: impl Foo) where (): From<<impl Foo as Foo>::Result> {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

Following either of those suggestions yields code that doesn’t compile, because impl Trait isn’t allowed in that position. Even if it becomes allowed someday, I feel like they would still be incorrect, since each impl Trait need not refer to the same type?

Ideally the output should look like:

[...]
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar<F: Foo>(foo: F) where (): From<F> + From<<F as Foo>::Result> {
  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Examples are on stable (1.53.0), but this also affects 1.54.0-nightly (44456677b 2021-06-12).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-trait-systemArea: Trait systemD-lack-of-suggestionDiagnostics: Adding a (structured) suggestion would increase the quality of the diagnostic.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