Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: Accept semicolons as item-like #2479
Conversation
Centril
added
the
T-lang
label
Jun 16, 2018
This comment has been minimized.
This comment has been minimized.
|
Another alternative is to allow the parser to accept ; as an item, while still making having one be a hard error. This happens with a number of different syntax errors so that the compiler can report all errors at once, rather than stopping immediately. |
This comment has been minimized.
This comment has been minimized.
|
@clarcharr I think that the proposal in the RFC is better, but I've made a note of that alternative in the RFC. Thank you for mentioning it. |
This comment has been minimized.
This comment has been minimized.
|
IIRC, the situation with There's one thing that's pretty common (for C reasons) and must work: if condition {
; // Do nothing
}, and it already works, but I'm not sure how exactly it's treated by parser and especially macros, because it's not treated as a statement. Regarding semicolon freely floating among items in modules, I think usual error recovery (report an error, skip the semicolon, continue parsing) would be enough. |
This comment has been minimized.
This comment has been minimized.
Why? To me, a left-over semicolon does not usually signify a logic bug that needs to be caught immediately, but rather a trivial style mistake that can easily be stripped with rustfmt. A third alternative is to allow it in the language but fire a warn-by-default lint; that satisfies your "needs to be caught immediately" condition. Also, I think this RFC is in line with the general policy on language grammar as outlined by @withoutboats. |
This comment has been minimized.
This comment has been minimized.
|
I think the RFC is well written, but I tend to favor "Make struct F {}; a non-fatal hard error". I simply don't come across this problem that often, and I feel like it will lead to widespread bad style, despite the proposed rustfmt change. My feelings are not very strong though... |
This comment has been minimized.
This comment has been minimized.
Thanks :)
Would a warn-by-default lint, as a more aggressive mechanism, satisfy your concern? EDIT: Since #1925 was merged, I haven't seen any widespread use of that syntax, widely considered bad style, and |
This comment has been minimized.
This comment has been minimized.
I think so.
In this case, I think the risk is much higher because the semicolon in |
This comment has been minimized.
This comment has been minimized.
|
@mark-i-m I thought "a non-fatal hard error" was a contradiction; what did you mean by that? A deny-by-default lint? A hard error that the compiler "understands" well enough that it can still produce warnings/errors/etc for all the code after the superfluous semicolon? Personally, the RFC as-written is almost what I'd want, but I'd also add a rustc warn-by-default lint against superfluous semicolons. Today, Rust technically has pretty consistent semicolon rules, which only appear inconsistent in practice because there's nothing loudly discouraging superfluous semicolons. I can see the argument that rustfmt is sufficient, but to me this feels very similar to the existing rustc lints against unusued variables, unused |
This comment has been minimized.
This comment has been minimized.
Great; I'll add it to the list of alternatives for now in a bit. I wouldn't mind changing to it as the main proposal. Let's see what @ExpHP says.
Fair enough, it does seem like a reasonable inference. I have two points regarding this:
That's a nice rationale :) |
This comment has been minimized.
This comment has been minimized.
Personally, I constantly misremember the semicolon rules in both C++ and Javascript, despite working on one or the other every single day. So to me, "other languages are different" is a good argument for making it not a hard error (because it does reduce speedbumps), but not an argument for making it rustfmt-only (because I make these mistakes out of ignorance or indifference; not because I have an aesthetic preference for any one language's semicolon rules). Though I have no idea how true that is of everyone else. |
This comment has been minimized.
This comment has been minimized.
ExpHP
commented
Jun 17, 2018
•
|
Right now I'm bothered by what @petrochenkov said: (emphasis mine)
Yikes! And indeed, this is visibly reflected in the
Perhaps we should not formulate this as "making |
This comment has been minimized.
This comment has been minimized.
ExpHP
commented
Jun 17, 2018
•
This comment has been minimized.
This comment has been minimized.
As I understand it, there are two ways that part of the compiler can report an error. A fatal error immediately ends compilation, whereas a non-fatal error allows the compilation to proceed a bit further so we can gather more errors. I think the the warn by default lint is a better solution, though. It seems more in line with things like warning for superfluous parens on if conditions.
It is a personal taste thing for me too. I think the warn by default lint removes the papercuts for c/c++ programmers while encouraging good style. |
This comment has been minimized.
This comment has been minimized.
|
Does this make this a valid Rust program? ;;;;;;;;;;;;;
fn main() { }Thats a bit more extreme that our grammar flexibility usually goes. Why not allow an optional There's precedent for allowing optional |
This comment has been minimized.
This comment has been minimized.
|
I'm very good at accidentally putting extra semicolons after braced structs, so I'm sympathetic here, but it's hard for me to judge what, if anything, should be done. I like the discussion so far. Personally, I've been pretty happy since the error changed from "unexpected token" to error: expected item, found `;`
--> src/lib.rs:3:22
|
3 | struct Foo { x: u32 };
| ^ help: consider removing this semicolon |
This comment has been minimized.
This comment has been minimized.
I was actually thinking about this too. I think @withoutboats has a good point. In addition too their point, though, I think making By making |
This comment has been minimized.
This comment has been minimized.
Oh man! This foils my plans to propose |
This comment has been minimized.
This comment has been minimized.
|
One other thing: This seems like a less likely error, but I think the following mistake becomes possible all of a sudden: #[my_attr]; // oops
fn foo() { ... } |
This comment has been minimized.
This comment has been minimized.
|
In if clauses, we do lint on extraneous if (true) { //~ WARNING unnecessary parentheses around `if` condition
}The situation between the two is very similar. Cpp requires In fact I as a programmer coming from Cpp got so annoyed by that warning that I allowed it. So even though I'm mildly against this RFC now, I guess I'd have liked back when I was fresh from Cpp. Given the precedent, I think that a warn by default lint as @Centril suggested would be a good idea. match v {
Enum::Foo => panic!(),
Enum::Baz => {
let k = boo();
k.foo();
}, // ~ USEFUL this comma is good 😎
Enum::Bar(b) => bar(b),
} |
This comment has been minimized.
This comment has been minimized.
comex
commented
Jun 18, 2018
•
Not that extreme, comparatively speaking. This is perfectly valid in C and C++: ;;;;;;;;;;;;;
int main() { }(Since I was curious: Extraneous semicolons are also valid in Java, JS (of course), Haskell, and Ruby, but not in C#, Swift, or Python. In Go they are allowed only within functions.) |
This comment has been minimized.
This comment has been minimized.
Yep, it does. But it also seems extremely fn main() {
;;;;;;;;;;;;; // <-- interestingly, there is no lint here... but rustfmt will strip it
fn foo() { }
}So... still that extreme?
It seems like the simpler alternative to make
Yes good point; I think it would be caught by a warn-by-default lint well tho :)
Yes, I think so. Let's switch over to a warn by default lint as the main proposal (in addition to rustfmt formatting which solves the lint for the user instantly). So... what should the name of the lint be? I see two categories of options here:
|
This comment has been minimized.
This comment has been minimized.
|
I still don't see "positive"/"constructive" motivation for this change, as opposed to "let's accept some more syntax because we can". In addition to these semicolons we have a ton of cases in the parser when we can recover from a missing or an extraneous token and continue compilation. Should we turn them into warnings as well? |
This comment has been minimized.
This comment has been minimized.
|
I am primarily interested in getting a warn-by-default lint on the redundant semicolons that we already allow today. Allowing them in more places seemed like a minor win for consistency and arguably removing a speedbump when refactoring, but I'm fine if macro compatibility concerns override that. |
This comment has been minimized.
This comment has been minimized.
The motivation is clearly not to accept more syntax just because we can. The positive motivation is to avoid disturbing the writing flow of some users due to frequently made trivial mistakes. You might not agree with it it, but it is a positive motivation.
What specific cases are you worried about wrt. making
Are they frequently made trivial mistakes with precedent from other places?
I'll let whoever wants to do that make the case for it, but I won't. Redundant
Not to me. By emitting a warning instead of a hard error, the code can be compiled and tests can be run, so it helps retain flow a lot more in my opinion. |
This comment has been minimized.
This comment has been minimized.
If this is a problem that needs solution, then we can have a compiler mode similar to gcc's
I don't remember right away, need to investigate a bit. |
This comment has been minimized.
This comment has been minimized.
|
Regarding the redundant semicolons lint, I think we should avoid linting in this case: fn foo() -> Foo {
return Foo;
}The ; can technically be removed, but many (most?) people still write it. |
This comment has been minimized.
This comment has been minimized.
@scottmcm Oh sure; that works, but then you also get all the fixes that may be entirely unrelated to removing |
This comment has been minimized.
This comment has been minimized.
|
@alercah No, because there are places where you actually want those. I even mentioned them earlier. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Jan 12, 2019
|
@Centril proposal cancelled. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Jan 12, 2019
•
|
Team member @Centril has proposed to postpone this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
rfcbot
added
proposed-final-comment-period
disposition-postpone
and removed
proposed-final-comment-period
disposition-merge
labels
Jan 12, 2019
Centril
removed
the
I-nominated
label
Jan 12, 2019
This comment has been minimized.
This comment has been minimized.
graydon
commented
Jan 12, 2019
|
Oppose. The rationale is weak and the alternative of "do nothing" is sufficient. Also every change to the semicolon rules has always had unanticipated effects. They are fragile and a bad idea to perturb. |
This comment has been minimized.
This comment has been minimized.
|
Fwiw from the POV of parser recovery I've always kinda wanted an interactive rustc mode where it makes assumptions about your code and continues to compile in the background, letting you validate the assumptions in a prompt (which also basically applies the suggestion to your code, rustfix-style) Rust is rife with cases where it refuses to compile something where there's one very likely option (that it tells you about!), I think most of my time writing rust is spent dealing with these after I write a large block of code. Item semicolons and turbofish are cases that newcomers tend to hit, but I still hit cases like import errors and block semicolons. It would be nice if rustc could go "hey, did you mean to do X here?", and silently continue with compilation in the background, assuming X. If you accept the prompt, it edits your code. If you reject it, it errors out. This could apply for obvious parse bugs, but it could also apply for missing imports and a subset of type errors. |
This comment has been minimized.
This comment has been minimized.
|
@Manishearth That is pretty interesting, perhaps it could be coupled with a good REPL (which feels needed for other reasons...)? |
This comment has been minimized.
This comment has been minimized.
|
I really love this idea, as someone who uses primarily |
This comment has been minimized.
This comment has been minimized.
|
Sounds to me like running |
estebank
referenced this pull request
Jan 14, 2019
Merged
Recover from item trailing semicolon #57585
Centril
added a commit
to Centril/rust
that referenced
this pull request
Jan 14, 2019
Centril
added a commit
to Centril/rust
that referenced
this pull request
Jan 14, 2019
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Feb 5, 2019
|
|
rfcbot
added
final-comment-period
and removed
proposed-final-comment-period
labels
Feb 5, 2019
This comment has been minimized.
This comment has been minimized.
ErichDonGubler
commented
Feb 13, 2019
|
Has anybody verified the question the first question still listed to to-resolve?
I understand if we're not sure at this point and that we need might want to do something like a crater run to supplement theory with empirical data, just curious if anybody knew the answer yet. |
This comment has been minimized.
This comment has been minimized.
|
@ErichDonGubler I haven't looked it in a while, but it's unlikely that it would create any ambiguities. |
rfcbot
added
finished-final-comment-period
and removed
final-comment-period
labels
Feb 15, 2019
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Feb 15, 2019
|
The final comment period, with a disposition to postpone, as per the review above, is now complete. By the power vested in me by Rust, I hereby postpone this RFC. |
Centril commentedJun 16, 2018
•
edited
;) is now legal, but not recommended, in areas where items are allowed, permitting a user to writestruct Foo {};, among other things.rustfmtwill remove any extraneous;.;are encountered, whether they be inside or outside anfnbody.To @ExpHP who co-authored this RFC with me.