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:
21
readme.md
21
readme.md
@@ -106,15 +106,18 @@ z : s32 = ---; // uninitialized
|
||||
```
|
||||
|
||||
Builtin type names (`s2`, `u8`, `bool`, `string`, …) are reserved and can't be used
|
||||
as bare value identifiers. A leading backtick at the **binding site** escapes one
|
||||
into a raw identifier — its text drops the backtick and it's never read as a type —
|
||||
so reserved spellings (and keywords) work as ordinary names. The backtick is needed
|
||||
only where the name is declared; a later bare reference in value position resolves
|
||||
to the binding, while a bare `s2` in type position is still the type. It works in
|
||||
every identifier position (local, global, parameter, field, function name, and the
|
||||
control-flow / capture / binding forms — destructure, `if`/`while` binding, `for`
|
||||
capture, match capture, `catch`/`onfail` tag), and a reserved-spelled function is
|
||||
bare-callable:
|
||||
as bare identifiers at **any** binding site — a value binding (`:=` / typed local /
|
||||
parameter), a `::` constant or function declaration, or a `::` type declaration
|
||||
(`struct` / `enum` / `union` / alias / `protocol` / …) — each is an error
|
||||
(`s2 :: 5` and `s2 :: (n) { … }` are rejected just like `s2 := 5`). A leading
|
||||
backtick at the binding site escapes one into a raw identifier — its text drops the
|
||||
backtick and it's never read as a type — so reserved spellings (and keywords) work
|
||||
as ordinary names. The backtick is needed only where the name is declared; a later
|
||||
bare reference in value position resolves to the binding, while a bare `s2` in type
|
||||
position is still the type. It works in every identifier position (local, global,
|
||||
parameter, field, function name, constant, and the control-flow / capture / binding
|
||||
forms — destructure, `if`/`while` binding, `for` capture, match capture,
|
||||
`catch`/`onfail` tag), and a reserved-spelled function is bare-callable:
|
||||
|
||||
```sx
|
||||
`s2 := 2.5; // value identifier "s2", distinct from the s2 type
|
||||
|
||||
Reference in New Issue
Block a user