feat(lang): reserved-name check covers :: const/fn/type decls + scope call rewrite to raw provenance [F0.6]
A bare reserved-type-name `::` declaration was silently accepted, and the
attempt-2 lowerCall rewrite then made a bare `s2 :: (…) {…}` function callable —
bypassing the backtick rule for handwritten sx. The reserved-name binding check
covered `:=` / typed-local / param / captures but NOT the `::` declaration form.
- ast: `ConstDecl`/`FnDecl` carry `is_raw` + `name_span` threaded from the parser
(parseConstBinding / parseFnDecl, all call sites incl. struct/impl methods).
- semantic_diagnostics: reject a bare reserved spelling at EVERY declaration-name
site — const, function (incl. struct/impl methods), struct/enum/union/error-set,
protocol, foreign-class, ufcs alias, namespaced/library/c-import name. Backtick
(`is_raw`) and the compiler's `#builtin` definition (`string :: []u8 #builtin`)
are the only exemptions; a value whose node is itself a named decl defers to
that node's own check.
- c_import: synthesized foreign fn_decls are `is_raw = true`, so a C function
whose own name collides with a reserved spelling (`int s2(int);`) imports and
bare-calls unedited.
- lower: scope the `.type_expr`→`.identifier` call rewrite to a callee FnDecl of
RAW provenance (`is_raw`) — only a backtick / `#import c` foreign fn can carry a
reserved-name spelling, so a non-raw match never gets rewritten.
- examples: 0153 (positive — backtick `::` const + fn, bare + tick call), 1140
(negative — bare `::` const + fn rejected).
- docs: specs.md + readme.md state the backtick is required at every binding site
including `::` const / function / type declarations; issue 0089 banner updated.
This commit is contained in:
22
specs.md
22
specs.md
@@ -17,14 +17,25 @@ 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 value binding (`:=` / typed local / parameter name) spelled as
|
||||
one of these is rejected: such a spelling parses as a *type*, not a value, so the
|
||||
address-of / autoref paths would mis-lower it.
|
||||
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.
|
||||
|
||||
```sx
|
||||
s2 := 2.5; // ERROR: 's2' is a reserved type name and cannot be used as an identifier
|
||||
s2 := 2.5; // ERROR: 's2' is a reserved type name and cannot be used as an identifier
|
||||
s2 :: 5; // ERROR — a `::` constant name is a binding site too
|
||||
s2 :: (n: s64) -> s64 { n } // ERROR — so is a function name
|
||||
s2 :: struct { x: s64; } // ERROR — and a type-declaration name
|
||||
```
|
||||
|
||||
(The stdlib's own builtin definitions — e.g. `string :: []u8 #builtin;` — are the
|
||||
sole exception: a `#builtin` constant defines the reserved type and is allowed.)
|
||||
|
||||
#### Backtick raw-identifier escape
|
||||
|
||||
A leading backtick makes the following identifier **raw**: its text excludes the
|
||||
@@ -52,7 +63,8 @@ capture and index, a match-arm capture, and a `catch` / `onfail` tag binding:
|
||||
|
||||
```sx
|
||||
`u8 := 100; // global
|
||||
`s2 :: (`s1: s64) -> s64 { `s1 } // function name + parameter
|
||||
`s2 :: 2.5; // constant declaration
|
||||
`u8 :: (`s1: s64) -> s64 { `s1 } // function name + parameter
|
||||
P :: struct { `s2: f64; } // struct field
|
||||
`u8, rest := pair(); // destructure name
|
||||
if `s16 := maybe() { } // optional binding
|
||||
|
||||
Reference in New Issue
Block a user