Skip to content

E0412 is correct but E0782 is emitted (in trait definitions) #116434

Closed

Description

@Colonial-Dev

Code

trait Foo {
    type Clone;
    fn foo() -> Clone
}

Current output

error[E0782]: trait objects must include the `dyn` keyword
 --> src/main.rs:4:17
  |
4 |     fn foo() -> Clone;
  |                 ^^^^^
  |
help: add `dyn` keyword before this trait
  |
4 |     fn foo() -> dyn Clone;
  |                 +++

For more information about this error, try `rustc --explain E0782`.

Desired output

Obviously this isn't helpful, as Clone isn't object safe. The correct error is E0412:

error[E0412]: cannot find type `Clone` in this scope
 --> src/main.rs:4:17
  |
4 |     fn foo() -> Clone;
  |                 ^^^
  |
help: you might have meant to use the associated type
  |
4 |     fn foo() -> Self::Clone;
  |                 ++++++

For more information about this error, try `rustc --explain E0412`.

Rationale and extra context

E0412 is correctly emitted if the associated type name is changed to not collide with any traits currently in scope. So:

trait Foo {
    type Bar;
    fn foo() -> Bar
}

Errors as expected.

I've also seen this confuse new users "in the wild" on Rustcord - that's what originally inspired me to file this issue.

Other cases

No response

Anything else?

No response

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Oct 4, 2023
  2. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 4, 2023
  3. added
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 8, 2023
  4. removed their assignment
    on Jan 14, 2024
  5. trevyn commented on Jan 20, 2024

    @trevyn
    Contributor

    @rustbot claim

  6. trevyn commented on Jan 20, 2024

    @trevyn
    Contributor

    It looks like #119752 (in the queue) changes this to E0038 without a suggestion (for edition 2021):

    error[E0038]: the trait `Clone` cannot be made into an object
      --> /Users/e/Documents/GitHub/rust/tests/ui/suggestions/issue-116434.rs:5:17
       |
    LL |     fn foo() -> Clone;
       |                 ^^^^^ `Clone` cannot be made into an object
       |
       = note: the trait cannot be made into an object because it requires `Self: Sized`
       = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
    

    A suggestion to -> impl Clone is also valid (and with the above pull appears for edition < 2021), but perhaps your -> Self::Clone makes more sense in context, if not exactly... great.

    Do you have any links or can share how this is tripping up other users?

  7. trevyn commented on Jan 20, 2024

    @trevyn
    Contributor

    Ah, apparently it's possible to produce multiple suggestions. I'll poke at it and see what comes out.

  8. Colonial-Dev commented on Jan 20, 2024

    @Colonial-Dev
    ContributorAuthor

    Do you have any links or can share how this is tripping up other users?

    It's been a while, but what I saw on the Discord went something like this:

    trait DbHandle {
        /* irrelevant, but not object safe */ 
    } 
    
    // Some lines away... 
    
    trait DbInterface {
        // (presumably assuming the namespaces don't overlap) 
        type DbHandle;
    
        fn handle() -> DbHandle;
    } 

    The user then gets the "please add dyn" message, which they follow.

    The compiler then tells them "sorry you can't dyn that," and they wind up in the Discord very confused about the mixed signals.

  9. trevyn commented on Jan 20, 2024

    @trevyn
    Contributor

    The problematic dyn suggestion is also gone from nightly: playground

    The type (trait) DbHandle is in scope, so I don't think E0412 (cannot find type in this scope) is correct.

    If it provides the correct suggestion though, it would definitely be an improvement to include that suggestion in the output. I don't see a clear way to get there from the E0038 code path though. :(

  10. trevyn commented on Jan 21, 2024

    @trevyn
    Contributor

    Making some progress on this, currently blocked on #120164

  11. trevyn commented on Jan 21, 2024

    @trevyn
    Contributor

    @rustbot label -D-invalid-suggestion

  12. removed
    D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
    on Jan 21, 2024
  13. trevyn commented on Jan 25, 2024

    @trevyn
    Contributor

    blocked on #120275

  14. added 2 commits that reference this issue on Jan 31, 2024
  15. trevyn commented on Feb 2, 2024

    @trevyn
    Contributor

    I have a PR ready to go for this that adds the Self:: suggestion on E0038, waiting for bors to merge #120530

  16. added 3 commits that reference this issue on Feb 13, 2024
  17. added a commit that references this issue on Feb 14, 2024
  18. added a commit that references this issue on Feb 16, 2024
    670bdbf
  19. added a commit that references this issue on Feb 16, 2024
    d745c3b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`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