Skip to content

Commit dfbf8cb

Browse files
committed
Some improvements
Mention type aliases Mention differences between unit structs / tuple struct constructors and `const` / `fn` items. Add more use cases for `TS{0: expr}`/`TS{0: pat}`
1 parent 82bb5a0 commit dfbf8cb

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

text/0000-adt-kinds.md

+30-18
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ Braced structs have 0 or more user-named fields and are defined only in type nam
4343
Braced structs can be used in struct expressions `S{field1: expr, field2: expr}`, including
4444
functional record update (FRU) `S{field1: expr, ..s}`/`S{..s}` and with struct patterns
4545
`S{field1: pat, field2: pat}`/`S{field1: pat, ..}`/`S{..}`.
46-
In all cases the path `S` of the expression or pattern is looked up in the type namespace.
46+
In all cases the path `S` of the expression or pattern is looked up in the type namespace (so these
47+
expressions/patterns can be used with type aliases).
4748
Fields of a braced struct can be accessed with dot syntax `s.field1`.
4849

4950
Note: struct *variants* are currently defined in the value namespace in addition to type namespace,
@@ -63,7 +64,7 @@ Unit structs can be thought of as a single declaration for two things: a basic s
6364
struct US {}
6465
```
6566

66-
and a constant with the same name
67+
and a constant with the same name<sup>Note 1</sup>
6768

6869
```
6970
const US: US = US{};
@@ -74,15 +75,16 @@ constant `US`) namespaces.
7475

7576
As a basic struct, a unit struct can participate in struct expressions `US{}`, including FRU
7677
`US{..s}` and in struct patterns `US{}`/`US{..}`. In both cases the path `US` of the expression
77-
or pattern is looked up in the type namespace.
78+
or pattern is looked up in the type namespace (so these expressions/patterns can be used with type
79+
aliases).
7880
Fields of a unit struct could also be accessed with dot syntax, but it doesn't have any fields.
7981

8082
As a constant, a unit struct can participate in unit struct expressions `US` and unit struct
8183
patterns `US`, both of these are looked up in the value namespace in which the constant `US` is
82-
defined.
84+
defined (so these expressions/patterns cannot be used with type aliases).
8385

84-
Note 1: the constant is not exactly a `const` item, there are subtle differences, but it's a close
85-
approximation.
86+
Note 1: the constant is not exactly a `const` item, there are subtle differences (e.g. with regards
87+
to `match` exhaustiveness), but it's a close approximation.
8688
Note 2: the constant is pretty weirdly namespaced in case of unit *variants*, constants can't be
8789
defined in "enum modules" manually.
8890

@@ -103,7 +105,7 @@ struct TS {
103105
}
104106
```
105107

106-
and a constructor function with the same name
108+
and a constructor function with the same name<sup>Note 2</sup>
107109

108110
```
109111
fn TS(arg0: Type0, arg1: Type1, arg2: Type2) -> TS {
@@ -117,17 +119,21 @@ and the value (the constructor function `TS`) namespaces.
117119
As a basic struct, a tuple struct can participate in struct expressions `TS{0: expr, 1: expr}`,
118120
including FRU `TS{0: expr, ..ts}`/`TS{..ts}` and in struct patterns
119121
`TS{0: pat, 1: pat}`/`TS{0: pat, ..}`/`TS{..}`.
120-
In both cases the path `TS` of the expression or pattern is looked up in the type namespace.
121-
Fields of a braced tuple can be accessed with dot syntax `ts.0`.
122+
In both cases the path `TS` of the expression or pattern is looked up in the type namespace (so
123+
these expressions/patterns can be used with type aliases).
124+
Fields of a tuple struct can be accessed with dot syntax `ts.0`.
122125

123126
As a constructor, a tuple struct can participate in tuple struct expressions `TS(expr, expr)` and
124127
tuple struct patterns `TS(pat, pat)`/`TS(..)`, both of these are looked up in the value namespace
125-
in which the constructor `TS` is defined. Tuple struct expressions `TS(expr, expr)` are usual
128+
in which the constructor `TS` is defined (so these expressions/patterns cannot be used with type
129+
aliases). Tuple struct expressions `TS(expr, expr)` are usual
126130
function calls, but the compiler reserves the right to make observable improvements to them based
127131
on the additional knowledge, that `TS` is a constructor.
128132

129-
Note: the automatically assigned field names are quite interesting, they are not identifiers
130-
lexically (they are integer literals), so such fields can't be defined manually.
133+
Note 1: the automatically assigned field names are quite interesting, they are not identifiers
134+
lexically (they are integer literals), so such fields can't be defined manually.
135+
Note 2: the constructor function is not exactly a `fn` item, there are subtle differences (e.g. with
136+
regards to privacy checks), but it's a close approximation.
131137

132138
## Summary of the changes.
133139

@@ -143,15 +149,21 @@ implement as well.
143149
This also means that `S{..}` patterns can be used to match structures and variants of any kind.
144150
The desire to have such "match everything" patterns is sometimes expressed given
145151
that number of fields in structures and variants can change from zero to non-zero and back during
146-
development.
152+
development.
153+
An extra benefit is ability to match/construct tuple structs using their type aliases.
147154

148155
New: Permit using tuple structs and tuple variants in braced struct patterns and expressions
149-
requiring naming their fields - `TS{0: expr}`/`TS{0: pat}`/etc. This change looks a bit worse from
150-
the cost/benefit point of view. There's not much motivation for it besides consistency and probably
151-
shortening patterns like `ItemFn(name, _, _, _, _, _)` into something like `ItemFn{0: name, ..}`.
152-
Automatic code generators (e.g. syntax extensions like `derive`) can probably benefit from the
156+
requiring naming their fields - `TS{0: expr}`/`TS{0: pat}`/etc.
157+
While this change is important for consistency, there's not much motivation for it in hand-written
158+
code besides shortening patterns like `ItemFn(name, _, _, _, _, _)` into something like
159+
`ItemFn{0: name, ..}` and ability to match/construct tuple structs using their type aliases.
160+
However, automatic code generators (e.g. syntax extensions) can benefit from the
153161
ability to generate uniform code for all structure kinds as well.
154-
The author of the RFC is ready to postpone or drop this particular extension at any moment.
162+
`#[derive]` for example, currently has separate code paths for generating expressions and patterns
163+
for braces structs (`ExprStruct`/`PatKind::Struct`), tuple structs
164+
(`ExprCall`/`PatKind::TupleStruct`) and unit structs (`ExprPath`/`PatKind::Path`). With proposed
165+
changes `#[derive]` could simplify its logic and always generate braced forms for expressions and
166+
patterns.
155167

156168
# Drawbacks
157169
[drawbacks]: #drawbacks

0 commit comments

Comments
 (0)