---
gap_intake_report: true
intake_model: "claude-opus-5[1m]"
intake_at: 2026-08-12T07:05:00Z
target_doc: ast-reference/declarations.md
target_doc_source_commit_before: 53b76e6d3009b8e6434d41573524c7ce5c499d23
target_doc_source_commit_after: 67149d1e03ebf1d4645ddd224ff4647a8ea5db53
gap_count: 7
actions:
  fixed: 7
  rejected_bogus: 0
  rejected_out_of_scope: 0
  deferred: 0
  escalated_to_finding: 0
---

# Gap-intake report for ast-reference/declarations.md

## Summary

This is a re-run of the gap-intake stage covering one gap,
`ca655cf14cfe`, which the previous cycle deferred on the grounds that
the binding path lay outside `watched_paths` and that `slangc` could
not be run on this host. Both grounds have since dissolved:
`regenerate.py show` now resolves `source/slang/slang-check-shader.cpp`
and `source/slang/slang-diagnostics.lua` as watched paths for this
page, and a native arm64 `slangc` at `build-arm64/Debug/bin/slangc`
runs here. Running it settled the gap, so `ca655cf14cfe` moves from
`deferred` to `fixed` and the tally is now seven `fixed`, nothing
rejected, deferred, or escalated. The other six verdicts and their
Evidence are carried forward unchanged from the previous cycle.

Running the compiler also refuted the gap's own `Suggested addition`,
which asked for a note that "a stand-alone compile of the module is
expected to fail". It does not fail. `slangc /tmp/gapca/tp.slang -o
tp.slang-module` on a file that both declares `type_param T;` and uses
`T` in an entry point exits 0 and writes a 9107-byte module; a target
compile of a file that declares a `type_param` and never uses it also
exits 0. What fails is generating target code from a *use*: `slangc
tp.slang -target hlsl -entry computeMain -stage compute` reports
`error[E38207]: global generic parameter used in code without a
concrete binding` pointed at the `type_param` token. The same error
appears for `__generic_value_param N : int;` read as a value, though
reading one as an array extent fails earlier and differently
(`error[E39999]: expression does not evaluate to a compile-time
constant`). The new callout states the fact the gap was reaching for
without absorbing the hypothesis's incorrect version of it.

One further hypothesis in the gap row — that the arguments may be
"supplied through the compilation API or command line" — is only half
right, and the document now says which half. `slangc -specialize float`
on the same file reports `error[E38025]: wrong number of specialization
arguments`, because `-specialize` accumulates onto
`rawEntryPoint.specializationArgs` and is handed to `addEntryPointEx`
(`source/slang/slang-options.cpp:3407`, `:4287-4296`), binding entry-
point parameters rather than the module's. The module-level path is the
API one: `Module::_collectShaderParams` makes the specialization
parameter and `Module::_validateSpecializationArgsImpl` consumes the
argument.

## Actions

| Gap ID | Action | Evidence | Fix summary |
| --- | --- | --- | --- |
| 2fede3d30d6e | fixed | `source/slang/slang-parser.cpp:4773-4791` — `parseStorageDeclBody` takes either a braced accessor list or a bare `;`, and the comment "empty body should be treated like `{ get; }`" sits on the semicolon branch, not on an empty `{ }`; `:4706-4728` — `parseAccessorDecl` calls `Unexpected(parser)` for any token that is not `get` / `set` / `ref`, so `property int p { return v; }` cannot parse. An empty `{ }` adds no member either, so both forms reach checking with zero accessors (corroborated at `source/slang/slang-check-decl.cpp:16602-16628`, outside `watched_paths`). The legality of `property int p { }` as a requirement is the verified form in `docs/generated/tests/design/ast-reference/declarations/accessordecl-implicit-getter-property.slang` and `accessordecl-implicit-getter-subscript.slang` | rewrote the `### AccessorDecl family` sentence to separate a statement body (a parse error) from the two no-accessor forms `{ }` and `;` that share the implicit-getter case |
| ecac3ca82a5b | fixed | `source/slang/slang-parser.cpp:4629-4634` — `parseFileDecl` creates the `FileDecl` and calls `parseDeclBody`, which at `:6292-6300` pushes the decl's own scope; contrast `parseTransparentBlockDecl` at `:4616-4627`, which parses into the *enclosing* container and so really is transparent. `source/slang/slang-ast-decl.h:900` — the include machinery's `FileDecl` is the one stored in `IncludeDeclBase::fileDecl`; `:1191-1196` declares `addSiblingScopeForContainerDecl` ("Add a sibling lookup scope for `dest` to refer to `source`"), the mechanism that makes such a scope transparent | added three sentences to `### NamespaceDecl, ModuleDecl, FileDecl` saying transparency belongs to the checker-built file scopes, not to a hand-written `__file_decl` block |
| ec5f9a6f1ce7 | fixed | `source/slang/slang-parser.cpp:5543-5589` — `parseAttributeSyntaxDecl` resolves the `: <class>` clause with `parser->astBuilder->findSyntaxClass(classNameAndLoc.name)` (`:5587`) followed by `SLANG_ASSERT(syntaxClass)` (`:5589`), so only a class the compiler was built with can be named; `:5534-5541` — the comment says attribute-specific code is not invoked during parsing and "all specialized behavior takes place during semantic checking", which is why placement rules come from the C++ class. All 110 uses are in `source/slang/core.meta.slang` (108, e.g. `:4381`) and `source/slang/hlsl.meta.slang` (2). The unknown-class internal error is already covered by `docs/generated/tests/_meta/findings/declarations-attribute-syntax-unknown-class-ice.yaml` and is deliberately not documented | reworded the `AttributeDecl` row to "binds the spelling ... to an AST attribute class the compiler already knows" and added an `attribute_syntax` paragraph to the `SyntaxDecl` callout |
| 91fe0f7f6aa5 | fixed | `source/slang/slang-parser.cpp:214` and `:6457-6472` — `Parser::ParseGLSLInterfaceBlock` is the only site that constructs a `GLSLInterfaceBlockDecl`, and a tree-wide grep finds no call to it, so the node is unreachable at this commit. The GLSL block forms go elsewhere: `:5866` (`buffer` -> `parseGLSLShaderStorageBufferDecl`), `:5881` (`uniform` -> `parseHLSLCBufferDeclWithLayout`), `:5891` (`in`/`out` -> `ParseBufferBlockDecl` with an empty wrapper name), all of which build a `StructDecl` + `VarDecl` pair at `:4010-4110` and add a `TransparentModifier` at `:4159` when no instance name is written. `:3530-3541` confirms the `options.allowGLSLInput` gate | set the row's `Grammar` to `(none)`, noted the node is unreached, and added a `### GLSLInterfaceBlockDecl` callout naming the three desugarings instead of inventing an example |
| d03e7f78dc55 | fixed | `source/slang/slang-parser.cpp:4979-4992` — `parseSemanticDecl` reads `semantic <name>` then `parseSemanticDeclBody`, which at `:4957-4977` requires a braced body; `:4917-4954` — `parseSemanticAccessorDecl` accepts only `get : <type>;` and `set : <type>;`, producing `SemanticGetterDecl` / `SemanticSetterDecl`. The two-line surface is the verified form in `docs/generated/tests/design/ast-reference/declarations/semanticdecl-typed-getter.slang` | added a `### SemanticDecl` callout with the `semantic MySem { get : int; }` / `struct S { int v : MySem; }` example |
| ba8f19c2205d | fixed | `source/slang/slang-parser.cpp:6490-6559` — `parseEnumDecl` parses the `: T` part with the same `parseOptionalInheritanceClause` a struct uses, so the tag type and any conformances become sibling `InheritanceDecl` children; no assignment to `tagType` appears anywhere in `slang-parser.cpp`, and `source/slang/slang-ast-decl.h:448` declares the field on `EnumDecl`. Which base becomes the tag type, and the default when none is written, are decided in `source/slang/slang-check-decl.cpp:12185-12299` — outside `watched_paths` and forbidden content per `_meta/prompts/ast-reference-declarations.md:63-64`, so they are left to `pipeline/03-semantic-check.md` | added the `enum E : uint8_t { A, B }` spelling and the base-list parse shape to `### EnumDecl and EnumCaseDecl`, and said the parser never sets `tagType` |
| ca655cf14cfe | fixed | Both halves are now in `watched_paths` (confirmed by `regenerate.py show ast-reference/declarations.md`). `source/slang/slang-check-shader.cpp:2798-2818`, inside `Module::_collectShaderParams` (`:2726`), turns a `GlobalGenericParamDecl` into a `SpecializationParam` of flavor `GenericType` and a `GlobalGenericValueParamDecl` into one of flavor `GenericValue`, appending both to `m_specializationParams`; `Module::_validateSpecializationArgsImpl` (`:3199-3212`) validates supplied `SpecializationArg`s against `getSpecializationParamCount()` and diagnoses `MismatchSpecializationArguments` when too few arrive. `source/slang/slang-diagnostics.lua:4619-4625` defines E38207 `unspecialized-global-generic-param-with-uses` with exactly the observed message; `:4402-4407` defines E38025. Surface confirmed at `source/slang/slang-parser.cpp:4384-4415`. Compiler runs with `build-arm64/Debug/bin/slangc` and `SLANG_ASSERT=release-assert-only`, on a file declaring `type_param T;` plus a `computeMain` that uses `T`: `slangc tp.slang -target hlsl -entry computeMain -stage compute -o /dev/null` gives `error[E38207]: global generic parameter used in code without a concrete binding` at `tp.slang:1:12` (exit 255); `slangc tp.slang -o tp.slang-module` exits 0 and writes the module; the same target compile of a file whose `type_param` is unused exits 0; and adding `-specialize float` gives `error[E38025]: wrong number of specialization arguments`, since `source/slang/slang-options.cpp:3407` and `:4287-4296` route `-specialize` to `addEntryPointEx` | added a `### GlobalGenericParamDecl and GlobalGenericValueParamDecl` callout giving the two spellings, the module-specialization-parameter role, and the E38207 / E38025 outcomes, and pointed both `## Nodes` rows at it |
