Skip to content

tuple variant error message is confusing #65386

Closed as not planned
Closed as not planned

Description

@ultrasaurus

originally described in blog post: https://www.ultrasaurus.com/2019/10/rust-whats-a-tuple-variant/

sample code:

fn get_num() -> Result<i32, &'static str> {
  let result = 4;
  OK(result)
}

error message:

error[E0425]: cannot find function `OK` in this scope
  --> examples/tuple.rs:13:3
   |
13 |   OK(result)
   |   ^^ help: a tuple variant with a similar name exists: `Ok`

Error message suggestions:

General terminology suggestions:

  • stop referring to "tuple-like enum" and "tuple-like struct" and instead come up with a more precise term, such as "named tuple" (or "typed tuple" but I like the former better) which could be declared as a struct or as part of an enum.
  • refer to the struct / enum use of tuples in the book, here: https://doc.rust-lang.org/1.7.0/book/primitive-types.html#tuples link to Tuple structs and create a similar titled sub-section of enum and include a link to that
  • standardize naming of struct and enum and create logical parallel: unit enum / unit struct OR enum unit variant / struct unit variant (I prefer the former with fewer words)
  • when you standardize on the names, consider annotate them here:
enum Message {
    Quit,                                           // unit enum
    ChangeColor(i32, i32, i32),    // tuple enum
    Move { x: i32, y: i32 },              // struct enum
    Write(String),                           // also a tuple enum
}

(by the way, the above example is very good serving as both an introduction to the section content and an easy syntax reference that is quick to find later)

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools
    on Oct 13, 2019
  2. estebank commented on Oct 13, 2019

    @estebank
    Contributor

    Tagging the docs team for the latter half of the ticket.

  3. Centril commented on Oct 13, 2019

    @Centril
    Contributor

    standardize naming of struct and enum and create logical parallel: unit enum / unit struct OR enum unit variant / struct unit variant (I prefer the former with fewer words)

    A "unit enum" suggests an enum with a single variant rather than the unit variant of an enum; I would call this a "enum unit variant", which is albeit more verbose, also more clear.

  4. ultrasaurus commented on Oct 13, 2019

    @ultrasaurus
    Author

    Missed one suggestion.. the first part of the error message is a bit misleading since it implies that Ok() is a function.

    Instead of:

     cannot find function `OK` in this scope
    

    it could be something like this:

     `OK` has not been been previously defined as a function, struct or enum
    
  5. ultrasaurus commented on Oct 13, 2019

    @ultrasaurus
    Author

    @Centril would it be typical/common for someone create an enum with a single variant? seems like that would be unlikely in normal practice. If so, I would use more words to describe the less common use case, such as "enum with single variant"

  6. Centril commented on Oct 13, 2019

    @Centril
    Contributor

    No it's not usual but e.g. "tuple enum" still makes a category mistake by conflating the data type itself with its constructors (the variant in this case). I think that paints a misleading mental model of the language, which is avoidable by including an additional word.

  7. ultrasaurus commented on Oct 13, 2019

    @ultrasaurus
    Author

    hmm... I was reading "tuple" in "tuple enum" as an adjective -- a descriptor (to me) doesn't necessarily change the data type.

    However, I agree that this is an important clarification (that I missed in early readings of the docs) about the difference between an enum and a struct, where enum variants are all the same type and the equivalent struct syntax creates multiple types. In practice, I wasn't confused, but wasn't really conscious of this nuance in a way I could have spoken about it.

    FYI: in case it is useful, I ran into an example of "unit enum" used in the wild: https://users.rust-lang.org/t/what-is-a-unit-variant/18468/2

  8. estebank commented on Oct 14, 2019

    @estebank
    Contributor

    Looking a bit into this, procuring the Span for std::option::Option::Some is proving to be difficult here because although we have the variant's DefId available in librustc_resolve, where we emit this error, we do not have access to the hir::Map, so we can't get the span that way. Trying to use the definition Ident's Span is also not feasible because everything that comes from std::prelude::v1::* has a DUMMY_SP. I think that the only way to support this would be to delay the resolution error until a later stage where the hir::Map is available to properly display the "Result::Ok defined here" label. On the other hand, we can fix this in a minimally intrusive way today for things defined in the current crate.

    @petrochenkov what do you think is the feasibility of having the prelude imports carry correct Spans pointing at the std locations? It seems to me that that approach would be incorrect.

  9. added a commit that references this issue on Oct 15, 2019
  10. petrochenkov commented on Oct 15, 2019

    @petrochenkov
    Contributor

    @estebank

    what do you think is the feasibility of having the prelude imports carry correct Spans pointing at the std locations?

    It's more about spans for all extern items than about spans from std prelude specifically.
    I tried to do that in #63149, but backed out the change due to some non-reproducible order in diagnostics. (Perhaps it's already fixed?)
    The dummy spans are used instead of actual spans in fn build_reduced_graph_for_external_crate_res.

  11. 7 remaining items

  12. ultrasaurus commented on Oct 17, 2019

    @ultrasaurus
    Author

    @estebank that would have definitely helped!

    If you can put some kind of break between the code from diff files, I think that would be more readable.

    Just in case it's nearby, the "cannot find function..." seems to conflict with "similarly named tuple variant".... would it be possible to change to "cannot find function or enum tuple variant..." at the top of your screenshot.

    Thanks for your attention to this detail!

  13. estebank commented on Oct 17, 2019

    @estebank
    Contributor

    Screen Shot 2019-10-16 at 9 34 14 PM

    The change made the PR size balloon in size, but I do think that this error and all others that were changed are now more accurate.

  14. ultrasaurus commented on Oct 17, 2019

    @ultrasaurus
    Author

    This is great!

    It would have helped me if "tuple variant" had the word "enum" near it. Would it be correct to say "enum tuple variant" ?

    Not intending to be nit-picky, just providing feedback. The given context should provide enough breadcrumbs for a novice :)

  15. Centril commented on Oct 17, 2019

    @Centril
    Contributor

    Would it be correct to say "enum tuple variant" ?

    Yeah it's correct. It just has some redundancy because a tuple variant always belongs to an enum. That said, redundancy can be useful.

  16. estebank commented on Oct 17, 2019

    @estebank
    Contributor

    Googling "tuple variant rust" leads me to believe that not mentioning it could be a stumbling block for a newcomer:


    Screen Shot 2019-10-17 at 10 38 34 AM


    vs "enum tuple variant rust":


    Screen Shot 2019-10-17 at 10 39 44 AM


    That being said, I'm tempted at tackling that in a more methodical way with [t-doc].

  17. added a commit that references this issue on Oct 27, 2019
  18. added a commit that references this issue on Oct 28, 2019
  19. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on Dec 8, 2019
  20. Dylan-DPC commented on May 23, 2024

    @Dylan-DPC
    Member

    It appears that this error message is no longer confusing and should be fine to close this issue. If there are any improvements, it will be better in a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.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