Summary

Do not identify

同定する、特定する
struct
構造、構造体
literals by searching for :. Instead define
定義する
a sub- category of expressions
which excludes struct
構造、構造体
literals and re-define for, if, and other expressions
which take
とる
an expression
followed
下記の、次に続く、追従する
by a block (or non-terminal
非終端記号
which can be replaced by a block) to take
とる
this sub-category, instead of all expressions.

Motivation

Parsing

構文解析する
by looking ahead is fragile - it could easily be broken if we allow
許可する、可能にする
: to appear
現れる
elsewhere in types (e.g., type ascription) or if we change struct
構造、構造体
literals to not require the : (e.g., if we allow
許可する、可能にする
empty
空の
structs
構造、構造体
to be written with braces,
括弧
or if we allow
許可する、可能にする
struct
構造、構造体
literals to unify field names to local variable
変数、ストレージ
names, as has been suggested in the past and which we currently do for struct
構造、構造体
literal patterns). We should also be able to give better error messages today if users make these mistakes. More worryingly, we might come up with some language
言語
feature in the future which is not predictable now and which breaks with the current system.

Hopefully, it is pretty rare

まれ
to use struct
構造、構造体
literals in these positions, so there should not be much fallout. Any problems can be easily fixed by assigning
代入する
the struct
構造、構造体
literal into a variable.
変数、ストレージ
However, this is a backwards incompatible change, so it should block 1.0.

Detailed design
設計(する)

Here is a simplified version of a subset

部分集合
of Rust's abstract syntax:
文法

e ::= x | e `.` f | name `{` (x `:` e)+ `}` | block | `for` e `in` e block | `if` e block (`else` block)? | `|` pattern* `|` e | ... block ::= `{` (e;)* e? `}`

Parsing

構文解析する
this grammar
文法
is ambiguous since x cannot be distinguished from name, so e block in the for expression
is ambiguous with the struct
構造、構造体
literal expression.
We currently solve this by using lookahead to find a : token
トークン
in the struct
構造、構造体
literal.

I propose the following adjustment:

e ::= e' | name `{` (x `:` e)+ `}` | `|` pattern* `|` e | ... e' ::= x | e `.` f | block | `for` e `in` e' block | `if` e' block (`else` block)? | `|` pattern* `|` e' | ... block ::= `{` (e;)* e? `}`

e' is just e without struct

構造、構造体
literal expressions.
We use e' instead of e wherever e is followed
下記の、次に続く、追従する
directly
直接
by block or any other non-terminal
非終端記号
which may have block as its first terminal (after any possible expansions).

For any expressions

where a sub-expression is the final lexical
字句的
element
要素
(closures in the subset
部分集合
above, but also unary
単項の
and binary
2進数
operations), we require two versions of the meta-expression - the normal one in e and a version with e' for the final element
要素
in e'.

Implementation

実装
would be simpler, we just add a flag to parser::restriction called RESTRICT_BLOCK or something, which puts us into a mode which reflects e'. We would drop in to this mode when parsing
構文解析する
e' position expressions
and drop out of it for all but the last sub-expression of an expression.

Drawbacks

It makes the formal grammar

文法
and parsing
構文解析する
a little more complicated (although it is simpler in terms
項、用語
of needing less lookahead and avoiding
避ける、回避する
a special case).

Alternatives
代わりのもの、選択肢

Don't do this.

Allow

許可する、可能にする
all expressions
but greedily parse
構文解析する
non-terminals
非終端記号
in these positions, e.g., for N {} {} would be parsed
構文解析する
as for (N {}) {}. This seems worse because I believe it will be much rarer to have structs
構造、構造体
in these positions than to have an identifier
識別子
in the first position, followed
下記の、次に続く、追従する
by two blocks (i.e., parse
構文解析する
as (for N {}) {}).

Unresolved questions

Do we need to expose this distinction anywhere

どこでも
outside of the parser? E.g., macros?