-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Reword error when data-less enum variant called as function #36520
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @pnkfelix (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
cd13bb8
to
25d08cf
Compare
My initial reaction: I don't think I've seen the phrase "data-less enum" before, and I'd prefer to try to use a phrase consistent with our docs, if possible. However, I do see "variant with no data" in the book. The book also uses "unit-like" elsewhere (in the context of "unit-like struct"), which I also see at rust-by-example cc @rust-lang/docs |
First time I see "data-less enum" expression as well. Sounds really strange. @jonathandturner: Has it been added in the update to the new error format maybe? |
It's called "unit variant"/"unit struct" in other resolution-related error messages. FWIW, I don't think all this extra cruft is an improvement. EDIT: the help line "did you mean to write |
Yeah, we have one for E0423 (#35796), though I'm happy to update if we have better wording. We've been trying to not use any technical terminology unless it's a part of the language (eg mutable is fine because of |
I used the terminology from the original ticket, but I agree the error message as is isn't great. I see some value in the errors for the different alternatives to have similar wording and format. The current error is a bit ambiguous, naming the enum's name, and a pointer to the variant's definition: error: expected function, found `Test`
--> file.rs:7:13
|
7 | let x = Test::Variant(1);
| ^^^^^^^^^^^^^^^^
|
note: defined here
--> file.rs:2:5
|
2 | Variant,
| ^^^^^^^ This gives you enough information to fix the issue, but I feel it is confusing for newcomers (as evidenced by #28533). A compromise might be doing: error: expected function, found `Test`
--> file.rs:7:13
|
7 | let x = Test::Variant(1);
| ^^^^^^^^^^^^^^^^ empty enum variant called like a function
|
= help: did you mean to write: `Test::Variant`?
note: defined here
--> file.rs:2:5
|
2 | Variant,
| ^^^^^^^ Also, I just tried using a struct variant as a unit variant, and there's no specialization in that error either, claiming it was called like a function: error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name
--> file.rs:8:13
|
8 | let y = Test::Variant2;
| ^^^^^^^^^^^^^^ struct called like a function
|
= help: did you mean to write: `Test::Variant2 { /* fields */ }`? |
It's in the book, in the reference, in other docs. |
@petrochenkov - we're updating the book to follow a similar scheme, where we only use terminology that will be necessary to understand the language as we go. Since we don't know the level of experience of the user when giving them an error message, it's better to err on the side of using language that more people can understand. It's totally okay for the reference and RFCs to be more technical, I think. |
@jonathandturner |
I agree with @petrochenkov here: people are using rust after all. If they don't know what a terminology is, it just means that they still need to learn it. Having a difference between "technical side" and any other side will bring more problems than solutions. |
@GuillaumeGomez - that's a fair point for terminology that's already established terms. I did a quick google through Google Scholar and didn't see either "unit struct" and "unit variant" mentioned, so I suspect these are terms we made up and there are easier ways to say those things. |
I'm pretty sure to already have saw them when I did ocaml, but maybe I'm wrong... Anyway, if there is another "official" terminology, we should fully switch to it (but I'm still pretty sure to have already saw them before...). |
New output error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name
--> unit.rs:8:13
|
8 | let y = Test::Variant2("World");
| ^^^^^^^^^^^^^^ struct called like a function
|
= help: did you mean to write: `Test::Variant2 { /* fields */ }`?
error: expected function, found unit variant `Test::Variant`
--> unit.rs:7:13
|
7 | let x = Test::Variant("Hello");
| ^^^^^^^^^^^^^^^^^^^^^^ unit enum variant called like a function
|
= help: did you mean to write: `Test::Variant`?
note: defined here
--> unit.rs:2:5
|
2 | Variant,
| ^^^^^^^
error: aborting due to previous error I defer the final wording to the team, but would like to know if the underlying code is sound. |
FWIW I have never liked the term "unit" (unit type, unit struct, etc). I know its origins in type theory and all but it doesn't really convey (to me) a strong sense of what it is and I don't think it's a term in widespread use. That said, I also don't like "data-less". It just doesn't...have a natural ring for me. "Empty enum variant" might be my favorite of the bunch, but maybe we can reword to avoid an adjective or in some other way? Some thoughts:
I see the value in sharing terminology between the book and the error messages -- but I think we should try to adopt terminology that is readily understood without having to go look it up. Basically I think avoiding "jargon" should be a high priority for us, so long as we are not introducing imprecision and confusion. |
☔ The latest upstream changes (presumably #36551) made this pull request unmergeable. Please resolve the merge conflicts. |
@nikomatsakis Any chance we could revise teminology in book and messaging to rename "unit enum variant" to "tag" ? Or is that already used to talk about the discriminant in general? Update: I proposed this b/c I was under impression that this was common terminology in PL (e.g. "type tag"), but a quick review of Google results lead me to doubt that theory. |
@pnkfelix I'm not aware of us saying "tag" much, I guess people sometimes say "tagged union"? |
2d23371
to
6afe86a
Compare
Some(print::expr_to_string(expr)) | ||
} else { None } | ||
} else { None } | ||
} else { None }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uuuuuuuurgh.
if adt_def.is_enum() { | ||
if let hir::ExprCall(ref expr, _) = call_expr.node { | ||
Some(print::expr_to_string(expr)) | ||
} else { None } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uuuuuuuurgh.
if let hir::ExprCall(ref expr, _) = call_expr.node { | ||
Some(print::expr_to_string(expr)) | ||
} else { None } | ||
} else { None } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uuuuuuuurgh.
ref t => { | ||
let unit_variant = if let &ty::TyAdt(adt_def, ..) = t { | ||
if adt_def.is_enum() { | ||
if let hir::ExprCall(ref expr, _) = call_expr.node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a None
variable and remove all else cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good for me.
☔ The latest upstream changes (presumably #36737) made this pull request unmergeable. Please resolve the merge conflicts. |
Given a file like: ```rust enum Test { Variant, Variant2 {a: u32}, } fn main(){ let x = Test::Variant("Hello"); let y = Test::Variant2("World"); } ``` The errors now look this way: ```bash error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name --> file3.rs:10:13 | 10 | let y = Test::Variant2("Hello"); | ^^^^^^^^^^^^^^ struct called like a function | = help: did you mean to write: `Test::Variant2 { /* fields */ }`? error: `Test::Variant` is being called, but it is not a function --> file3.rs:9:13 | 9 | let x = Test::Variant("World"); | ^^^^^^^^^^^^^^^^^^^^^^ | = help: did you mean to write: `Test::Variant`? note: defined here --> file3.rs:2:5 | 2 | Variant, | ^^^^^^^ error: aborting due to previous error ```
6a13b65
to
a449bdb
Compare
Rebased to fix merge conflict and squash history. |
r? @pnkfelix |
📌 Commit a449bdb has been approved by |
⌛ Testing commit a449bdb with merge bca365e... |
Reword error when data-less enum variant called as function Given a file like: ``` rust enum Test { Variant, Variant2 {a: u32}, } fn main(){ let x = Test::Variant("Hello"); let y = Test::Variant2("World"); } ``` Both errors now look similar: ``` bash error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name --> file3.rs:10:13 | 10 | let y = Test::Variant2("Hello"); | ^^^^^^^^^^^^^^ struct called like a function | = help: did you mean to write: `Test::Variant2 { /* fields */ }`? error: `Test::Variant` is the name of a data-less enum, but this expression uses it like a function name --> file3.rs:9:13 | 9 | let x = Test::Variant("World"); | ^^^^^^^^^^^^^^^^^^^^^^ data-less enum called like a function | = help: did you mean to write: `Test::Variant`? note: defined here --> file3.rs:2:5 | 2 | Variant, | ^^^^^^^ error: aborting due to previous error ``` Re: #28533
Given a file like:
Both errors now look similar:
Re: #28533