docs(lang): precise reserved-name rule — member-name positions are EXEMPT [F0.6]
AGRA RULING (issue 0089, attempt 7): bare reserved-name MEMBER positions are intentionally exempt from the reserved-type-name rule, and the implementation already does the right thing — this is a docs + one-example change, no code. The exempt member positions are struct FIELD names, union TAG names, and protocol method-SIGNATURE names: they sit in a member slot, are reached via obj.name (or dispatched by string), and are never type-classified, so they never mis-lower. The backtick is optional there. The exemption stops at member DEFINITIONS: an impl method is a real function (reached through the impl_block -> fn_decl arm), so a reserved-spelled impl method still needs the backtick, exactly like a free function (cf. examples/1122) — and every bare reserved-name value binding / declaration name still errors (0076 preserved). - specs.md / readme.md: replace the "every binding site" / "any binding site" overclaim with the precise rule — required positions (value bindings + declaration names + impl method definitions) vs the exempt member-name positions (field / tag / protocol signature; backtick optional). - examples/0158-types-reserved-name-member-exempt.sx: pins the exempt behavior — bare reserved-name struct fields + union tag read & written bare AND via backtick, and a protocol with a bare reserved-name method dispatched through the protocol (impl definition takes the backtick). - issues/0089: document the member-name exemption in the RESOLVED banner + add 0158 to the regression list. Gate: zig build, zig build test, bash tests/run_examples.sh — all green (430 passed, 0 failed, 0 timed out).
This commit is contained in:
34
specs.md
34
specs.md
@@ -17,14 +17,26 @@ Line comments start with `//` and extend to end of line.
|
||||
|
||||
A spelling that names a builtin type — the arbitrary-width integers `s1`..`s64` /
|
||||
`u1`..`u64`, plus `bool`, `string`, `void`, `f32`, `f64`, `usize`, `isize`, `Any` —
|
||||
is reserved. A bare reserved spelling is rejected at **every binding site** —
|
||||
anywhere handwritten sx introduces a name: a value binding (`:=` / typed local /
|
||||
parameter), a `::` **constant** or **function** declaration, and a `::` **type**
|
||||
declaration (`struct` / `enum` / `union` / `error` / type alias / `protocol` /
|
||||
foreign class / ufcs alias / namespaced import). A value-spelled-as-type parses as
|
||||
a *type*, not a value, so its address-of / autoref paths would mis-lower; a
|
||||
type/const/function name spelled as a builtin would shadow the builtin. The only
|
||||
exemptions are the backtick escape (below) and `#import c` foreign decls.
|
||||
is reserved. A bare reserved spelling is rejected at **value-binding and
|
||||
declaration-name sites**: a value binding (`:=` / typed local / parameter), a
|
||||
`::` **constant** or **function** declaration, an `impl` method **definition**,
|
||||
and a `::` **type** declaration (`struct` / `enum` / `union` / `error` / type
|
||||
alias / `protocol` / foreign class / ufcs alias / namespaced import). A
|
||||
value-spelled-as-type parses as a *type*, not a value, so its address-of /
|
||||
autoref paths would mis-lower; a type / const / function / method name spelled as
|
||||
a builtin would shadow the builtin. The exemptions are the backtick escape
|
||||
(below), `#import c` foreign decls, and **member-name positions** (next) — it is
|
||||
**not** rejected at every place a name appears.
|
||||
|
||||
**Member-name positions are exempt.** A struct **field** name, a union **tag**
|
||||
name, and a protocol **method-signature** name may be a bare reserved spelling.
|
||||
These sit in a member slot (`name: T` / `name :: (…)`) and are reached only via
|
||||
`obj.name` (or dispatched by string), so they are never type-classified and never
|
||||
mis-lower. The backtick form is optional there and names the same member — `obj.s2`
|
||||
and `` obj.`s2 `` both resolve. The exemption covers member *signatures* only: an
|
||||
`impl` method **definition** is a real function (a declaration site, not a member
|
||||
slot), so a reserved-spelled impl method still needs the backtick
|
||||
(`` `s2 :: (self) ``), exactly like a free function. See `examples/0158`.
|
||||
|
||||
```sx
|
||||
s2 := 2.5; // ERROR: 's2' is a reserved type name and cannot be used as an identifier
|
||||
@@ -91,6 +103,12 @@ for xs: (`bool, `u16) { } // for capture + index
|
||||
x catch `s2 { } // catch tag binding
|
||||
```
|
||||
|
||||
In the **member-name positions** among these — struct field, union tag, and
|
||||
protocol method signature — the backtick is *optional*: the bare reserved
|
||||
spelling is already legal there (see "Member-name positions are exempt" above).
|
||||
Everywhere else (value bindings and declaration names, including an `impl` method
|
||||
definition) the backtick is *required* to spell a reserved name.
|
||||
|
||||
A reserved-spelled **function** is bare-callable: `` `s2 :: (n: s64) -> s64 { … } ``
|
||||
can be invoked as `s2(10)` (the bare callee spelling parses as a type but resolves
|
||||
to the function when one of that name is in scope; `TypeName(val)` is not a cast).
|
||||
|
||||
Reference in New Issue
Block a user