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:
@@ -16,6 +16,17 @@
|
||||
> ([src/ir/semantic_diagnostics.zig]). The backtick works in every identifier
|
||||
> position (local, global, param, field, function name, struct member, later
|
||||
> reference, and all the control-flow/capture/binding forms).
|
||||
>
|
||||
> The `::` DECLARATION forms are binding sites too and are equally covered
|
||||
> (F0.6 attempt-3): a bare reserved-name **constant** (`s2 :: 5`), **function**
|
||||
> (`s2 :: (…) {…}`, incl. struct/impl methods), or **type** declaration
|
||||
> (`struct`/`enum`/`union`/`error`/alias/`protocol`/foreign-class/ufcs/namespace)
|
||||
> is rejected, exactly like `s2 := …`. `ConstDecl`/`FnDecl` carry `is_raw` +
|
||||
> `name_span` threaded from the parser (`parseConstBinding`/`parseFnDecl`), so the
|
||||
> backtick form (`` `s2 :: … ``) is exempt; the compiler's own builtin definition
|
||||
> (`string :: []u8 #builtin`) is the sole non-backtick exemption (a `#builtin`
|
||||
> constant defines the reserved type). This closed the attempt-2 hole where a
|
||||
> bare `s2 :: (…) {…}` compiled silently and the call rewrite made it callable.
|
||||
> 2. **`#import c` foreign-name exemption.** `c_import.zig` synthesizes foreign
|
||||
> `#foreign` decls with `Param.is_raw = true`, so generated C param names that
|
||||
> collide with reserved type names (`s1`, `s2`) import unedited.
|
||||
@@ -24,8 +35,11 @@
|
||||
> one in type position (`x : `s2 = 1`) is a clean parse error ([src/parser.zig]
|
||||
> `parseTypeExpr` atom). A reserved-spelled FUNCTION (backtick-declared or
|
||||
> `#import c` foreign) is bare-callable: `lowerCall` rewrites a `.type_expr` callee
|
||||
> to an identifier when a function of that name is in scope ([src/ir/lower.zig]),
|
||||
> so `s2(4)` resolves to the function (`TypeName(val)` is not a cast). A later BARE
|
||||
> to an identifier when a function **of RAW provenance** of that name is in scope
|
||||
> ([src/ir/lower.zig]) — the rewrite is scoped to the callee `FnDecl`'s `is_raw`
|
||||
> flag (F0.6 attempt-3), so it only ever fires for a backtick / `#import c` foreign
|
||||
> fn (the decl check guarantees no bare reserved-name fn exists), so `s2(4)`
|
||||
> resolves to the function (`TypeName(val)` is not a cast). A later BARE
|
||||
> reference in value position resolves to the binding; a bare `s2` in type position
|
||||
> is still the type.
|
||||
>
|
||||
@@ -38,7 +52,11 @@
|
||||
> (foreign param + function-name exemption, bare-callable foreign fn),
|
||||
> `examples/1139-diagnostics-backtick-raw-not-a-type.sx` (negative — raw in type
|
||||
> position), `examples/1119`/`1121`/`1123` (negative — bare reserved binding still
|
||||
> rejected across all forms). Backtick lexer unit tests in `src/lexer.zig`.
|
||||
> rejected across all forms),
|
||||
> `examples/0153-types-backtick-const-fn-decl.sx` (positive — backtick `::` const +
|
||||
> function decl, bare + backtick call), and
|
||||
> `examples/1140-diagnostics-reserved-name-const-fn-decl.sx` (negative — bare `::`
|
||||
> const + function decl rejected). Backtick lexer unit tests in `src/lexer.zig`.
|
||||
>
|
||||
> The original report is preserved below.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user