I don't think an RFC for this exists yet, it's just a simple idea: A struct literal, e.g. Struct { field: value }
can be written as _ { field: value }
, when the type can be inferred, e.g. in a function argument. This is more concise and reduces boilerplate by requiring fewer imports. The _
as a placeholder feels like the obvious choice, since it's already used for omitting a type that can be inferred, e.g. Vec<_>
.
The syntax { field: value }
without an underscore is also a possibility, and looks appealing because JavaScript and Python have a similar syntax. However, it has some problems (which also apply to record types as proposed in this thread btw):
First, it's ambiguous with blocks in several situations, e.g.
- when there are no fields:
{}
- when there's a single field using the shorthand syntax:
{ field }
instead of { field: field }
- when all fields are omitted:
{ ..default() }
JavaScript's syntax has a deliberate limitation because of this: When returning an object from an arrow function, the object must be wrapped in parentheses, e.g. (x, y) => ({ x, y })
. But note that adding parentheses would not work in Rust, since blocks are expressions in Rust, and can appear anywhere.
The other problem with the { field: value }
syntax is that it looks so similar to a block that it may negatively impact diagnostics. For example, when you write Struct { field = 42 }
, Rust will tell you to replace the =
with a :
. This useful diagnostic likely wouldn't work for { field = 42 }
.
What's nice about _{}
or .{}
is that it can be trivially extended to other parts of Rust. For example, _::Variant
could become a shorthand for SomeEnum::Variant
. Tuple structs and unit structs could be inferred as well with _()
and _
, although _()
would be more controversial, because constructing a tuple struct is just a function call, strictly speaking.
One common argument against any proposal to make syntax more concise is explicitness: People argue that being forced to specify types explicitly makes the code easier to understand. I'd say this ship has sailed, since Rust already has powerful type inference and doesn't require specifying types in many places. Also, Rust's design has always been about giving programmers as much freedom as possible, instead of forcing them to follow certain paradigms. Rust devs can specify types everywhere if they think it helps them, but they don't have to.