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

forbid redundant semicolons #5905

Closed
thestinger opened this issue Apr 16, 2013 · 6 comments
Closed

forbid redundant semicolons #5905

thestinger opened this issue Apr 16, 2013 · 6 comments
Labels
A-parser Area: The parsing of Rust source code to an AST

Comments

@thestinger
Copy link
Contributor

Currently valid:

fn main() {
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
}

I don't think there's a good reason to allow a semicolon except after an actual statement.

@jbclements
Copy link
Contributor

Yes, I noticed this a few days ago as well. This is probably as good a place as any to conduct a very short review of the grammar for blocks that I'm observing in the parser.

The first thing to note is that like many languages, an expression may be used as a statement by putting a trailing semicolon after it.

However, unlike many languages, in Rust the term "if true {3} else {4}" is a legal expression. At the same time, Rust programmers would prefer not to have to put a semicolon after this expression to make it a statement.

This raises a potential ambiguity. Specifically, how should we parse
if true {3} else {4}
|a|a
?
It could be parsed as an if statement followed by a closure, or as two uses of the or (|) operator.

Finally, there's a Rust-ism (that I'm quite fond of) that allows a programmer to use a final expression as a return value, as long as it's not terminated by a semicolon.

So, here's what I've currently got:

fun_body : LBRACE inner_attr* block_element* block_last_element? RBRACE ;
block_element : expr_no_lhs_stmt (SEMI)+
  | stmt_not_just_expr (SEMI)*
  ;

// a statement that is not parsed by the expr_no_lhs_stmt rule
stmt_not_just_expr : let_stmt
  | macro_expr
  | mod_item
  | expr_stmt
  ;

block_last_element : expr_no_lhs_stmt | mac_expr | expr_stmt ;

Several definitions are omitted here. The 'expr-no-lhs-stmt' is a production that allows any expression except one that begins with a complete statement, as e.g. ethe 'if' example above. The expr_stmt rule is one that only includes those forms. A mod_item is a "module item", e.g. a function declaration, structure declaration, etc.

I'm not yet convinced that this grammar is correct or unambiguous. To address your concern, you'd probably want to change some of these rules, e.g. changing (SEMI+) into SEMI and (SEMI)* into /nothing/... but you'd want to allow an optional trailing semicolon before the RBRACE, to signal that an expression's value should not be returned.

Thoughts?

@toddaaro
Copy link
Contributor

toddaaro commented Jul 3, 2013

Nominating for backwards compatible. I personally think we shouldn't allow this - so I flagged it with wrong.

@huonw
Copy link
Member

huonw commented Jul 3, 2013

FWIW, being flexible with semicolons and commas makes writing macros easier.

@jbclements
Copy link
Contributor

+1 to @huonw ; this strikes me as relatively unlikely to be indicative of erroneous code. I'm not actually sure it'll help with macros, though; the expr/statement boundaries are fixed before macro expansion occurs.

@graydon
Copy link
Contributor

graydon commented Aug 22, 2013

accepted for backwards-compatible milestone

@catamorphism
Copy link
Contributor

Wontfix for reasons stated by @huonw and @jbclements - closing

flip1995 pushed a commit to flip1995/rust that referenced this issue Aug 28, 2020
docs: typo in `temporary_cstring_as_ptr`: s/point/&s

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parser Area: The parsing of Rust source code to an AST
Projects
None yet
Development

No branches or pull requests

6 participants