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

Incorrect suggestion when trying to implement Trait<Associated = ()> with impl Trait + 'static #87261

Closed
patrick-gu opened this issue Jul 18, 2021 · 0 comments · Fixed by #87348
Labels
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.

Comments

@patrick-gu
Copy link
Contributor

Given the following code (Playground):

trait Trait {
    type Associated;
}

fn returns_opaque() -> impl Trait + 'static {
    struct Impl;

    impl Trait for Impl {
        type Associated = ();
    }

    Impl
}

fn accepts_trait<T>(_: T)
where
    T: Trait<Associated = ()>,
{
}

fn main() {
    accepts_trait(returns_opaque());
}

The current output is:

   Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
  --> src/main.rs:22:5
   |
5  | fn returns_opaque() -> impl Trait + 'static {
   |                        -------------------- the found opaque type
...
15 | fn accepts_trait<T>(_: T)
   |    ------------- required by a bound in this
16 | where
17 |     T: Trait<Associated = ()>,
   |              --------------- required by this bound in `accepts_trait`
...
22 |     accepts_trait(returns_opaque());
   |     ^^^^^^^^^^^^^ expected `()`, found associated type
   |
   = note:    expected unit type `()`
           found associated type `<impl Trait as Trait>::Associated`
help: consider constraining the associated type `<impl Trait as Trait>::Associated` to `()`
   |
5  | fn returns_opaque() -> impl Trait + 'static<Associated = ()> {
   |                                            ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

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

To learn more, run the command again with --verbose.

The syntax impl Trait + 'static<Associated = ()> does not actually work.

Ideally the suggested fix should look like:

help: consider constraining the associated type `<impl Trait as Trait>::Associated` to `()`
   |
5  | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
   |                                  ^^^^^^^^^^^^^^^^^

This bug appears to be present in stable, beta, and nightly, on both Rust 2015 and 2018.

@patrick-gu patrick-gu 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 Jul 18, 2021
JohnTitor added a commit to JohnTitor/rust that referenced this issue Jul 24, 2021
Fix span when suggesting to add an associated type bound

Fixes rust-lang#87261

Note that this fix is not perfect, it ~~will still give incorrect~~ won't give suggestions in some situations:
- If the associated type is defined on a supertrait of those contained in the opaque type, it will fallback to the previous behaviour, e.g. if `AssocTy` is defined on the trait `Foo`, `Bar` has `Foo` as supertrait and the opaque type is a `impl Bar + Baz`.
- If the the associated type is defined on a generic trait and the opaque type includes two versions of that generic trait, e.g. the opaque type is `impl Foo<A> + Foo<B>`
@bors bors closed this as completed in e4d8f0e Jul 24, 2021
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 T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant