rust-lang / rust-lang/reference

Document Restrictions::STMT_EXPR better

Open
#1,809 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-grammar
Dominant language
Rust
Stars
1.6k
Forks
607
PR merge metrics
PR metrics pending

Description

The Restrictions::STMT_EXPR restriction could be better documented. Currently we have:

  • The Expression grammar is split into ExpressionWithoutBlock and ExpressionWithBlock. These are used somewhat to indicate that block-like expressions have different behavior in different places.
  • statement.expr.restriction-semicolon tries to explain the ambiguity of how a block expression is not treated as part of another expression in statement positions.

In statement position, if match blocks (except async) while loop for try const stop parsing in certain ways and do not follow things like associative operators. This is used in various places like statement position, but also match arms, etc.

This restriction has many consequences, like in the following examples:

// In statement position, this is two statements.
// Otherwise it is a call on the value of the `if` expression.
if true {}
(1,2,3)

// This fails to parse. `{1}` is a statement (parsing stops at `+` due to STMT_EXPR).
// `+{2}` (or `+2`) is not a valid statement or expression.
{{1}+{2}};

    // These modifications work:
    {1 + {2}};
    {({1}) + {2}};

// Same as above, fails since the `match` is a statement, parsing stops at `+`.
match () { () => 1 } + 2;

// This parses (two statements, a block and an unary `-` expression), then
// fails typecheck because blocks without semicolon need to be unit.
{1}-1;

// This works because STMT_EXPR does *not* stop parsing on `.`.
{"abc"}.len();

Various things to consider:

  • Need to double check that the existing parts are covered correctly and completely.
  • Document where "statement position" is? Not sure if existing grammar handles this well enough.
  • See notes in #1808 about how this state is "sticky", and should document where it starts and ends.
    • I don't know how this should be encoded in the grammar. Currently we try with splitting Expression in two, but like #1808 this runs into problems since the state is maintained while recursing. Maybe this should use suffixes like that issue instead? I don't really know how that should be approached.

See all the calls to expr_is_complete(), which is one of the key parts of how this works.

See https://github.com/rust-lang/reference/issues/569 for the previous issue for this.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked Restrictions::STMT_EXPR definition in compiler/rustc_parse/src/parser/mod.rs and the statement.expr.restriction-semicolon section in the Rust Reference. Then inspect the expr_is_complete() call sites and the examples in this issue. Done means the Reference explains where the restriction starts and ends, its statement-position behavior and consequences, and covers the existing cases accurately.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.