---
gap_intake_report: true
intake_model: "claude-opus-5[1m]"
intake_at: 2026-08-11T16:09:27Z
target_doc: ast-reference/modifiers.md
target_doc_source_commit_before: 53b76e6d3009b8e6434d41573524c7ce5c499d23
target_doc_source_commit_after: ec47ea72b6aa5fefc3b36f8a780dbd3ecf5b1f6e
gap_count: 14
actions:
  fixed: 11
  rejected_bogus: 0
  rejected_out_of_scope: 1
  deferred: 2
  escalated_to_finding: 0
---

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

## Summary

Nothing was escalated: every observation that could be checked agreed
with the watched source, and the two that disagreed with the document
(`ref` / `borrow` spellings, and the GLSL matrix-layout classes) turned
out to be document errors rather than compiler defects. Eleven gaps were
fixed by editing eight sections of the target document, all of them
confirmed against `source/slang/core.meta.slang` `attribute_syntax` doc
comments or `source/slang/slang-parser.cpp` modifier/decl construction
sites. One gap was rejected as out of scope (emitted-HLSL shapes belong
to the target-pipeline pages, and the AST-reference contract forbids
code blocks in `## Notable nodes`). Two were deferred because the only
source that settles them — `source/slang/slang-check-modifier.cpp` — is
not in this document's `watched_paths`, so documenting from it would
leave an untracked claim.

Operator follow-ups: (1) adding `source/slang/slang-check-modifier.cpp`
to this document's `watched_paths` would unblock both deferred gaps
(`getModifierConflictGroupKind` at lines 1564-1673 is the single source
of truth for which modifiers are mutually exclusive) and would also let
the diagnostic half of `5f1d93fb6c31` be recorded; (2) the doc-comment
for `[open]` in `core.meta.slang` marks both inheritance-control
attributes `@experimental`, which the page does not currently say —
left alone as outside the gaps.

## Actions

| Gap ID | Action | Evidence | Fix summary |
| --- | --- | --- | --- |
| 8afbb1ec5eab | fixed | `source/slang/core.meta.slang:4750` declares `attribute_syntax [format(format : String)]` and `:4757` the `vk_image_format` alias with the same `String` parameter; bundle tests `format-attribute-emits-spirv-image-format.slang` / `vk-image-format-alternate-spelling.slang` compile the quoted forms. | quoted the format argument in the `FormatAttribute` row and stated that the parameter is a `String`, so a bare identifier is not accepted |
| 5f1d93fb6c31 | fixed | `source/slang/slang-parser.cpp:6546` attaches `UnscopedEnumAttribute` only when the enum was *not* written `enum class`, and `:6553-6558` attaches `EnumClassModifier` for the `enum class` spelling with the comment "insert a modifier for conflicting unscoped/scoped enum detection". | named the concrete conflicting shape — explicit `[UnscopedEnum]` on an `enum class` — in the `EnumClassModifier` row; the diagnostic code is deliberately not cited, see the deferred note for `3d47ed25d143` |
| 51323cae9ecb | fixed | `source/slang/core.meta.slang:4461-4463` ("a hint to the downstream compiler ... does not affect Slang compiler's behavior") and `:4467-4468` ("Instructs the Slang compiler to unroll the loop ... before emiting targett code"); bundle tests `unroll-attribute-on-hlsl.slang` and `force-unroll-attribute-eliminates-loop.slang` pin the two emitted shapes. | stated in each row which side performs the unrolling, and corrected the `ForceUnroll` spelling to carry its optional count |
| 2ec18ad3db6a | fixed | `source/slang/core.meta.slang:4449-4450` ("cases of an unscoped enum are not scoped within the enum type, and can be referenced directly without the enum type name") and `source/slang/slang-parser.cpp:5772-5790`, which adds a `static const` `LetDecl` per case to the enclosing container. | added the scoping consequence and its mechanism to the `UnscopedEnumAttribute` row |
| 889f750e3aa0 | fixed | `source/slang/core.meta.slang:4454` ("Bit flag enums will have their enum cases assigned to powers of 2 instead of consecutive integers"); bundle test `flags-attribute-assigns-power-of-two.slang` checks `r=1 w=2 e=4`. | replaced the bare `[Flags]` spelling with the power-of-two numbering rule |
| 7093d566bc8f | fixed | `source/slang/core.meta.slang:4849` (`[sealed]` "preventing it from being inherited from or implemented by types defined in other modules") and `:4855-4856` (`[open]` "allowing it ... This is the default behavior"); bundle test `sealed-interface-allows-direct-conformance.slang` shows same-module conformance still checks. | stated the unannotated default and named the cross-module relationship `[sealed]` rejects, in both inheritance-control rows |
| 0977ade69342 | deferred | Only two of the eleven have a parse-time origin inside the watched paths — `ActualGlobalModifier` from the `__global` keyword (`source/slang/slang-parser.cpp:10776`) and `OptionalConstraintModifier` (`:1960`, `:1978`, `:2033`, `:2050`). The other nine are attached by the semantic checker (e.g. `IgnoreForLookupModifier` at `source/slang/slang-check-decl.cpp:12297`, `ExtensionExternVarModifier` at `source/slang/slang-check-modifier.cpp:2094`), all outside `watched_paths`; an "Introduced by" column would therefore carry nine untracked claims. Needs a `watched_paths` expansion to the `slang-check-*.cpp` set. | — |
| 3d47ed25d143 | deferred | The six interpolation modes are mutually exclusive — they share one conflict group in `getModifierConflictGroupKind` (`source/slang/slang-check-modifier.cpp:1648-1654`) and a second one in the group raises `duplicate-modifier`, error 31202 (`source/slang/slang-check-modifier.cpp:2522-2530`, `source/slang/slang-diagnostics.lua:2989-2994`). Neither file is in `watched_paths`, and no bundle test pins the conflict, so the rule cannot be written down under this cycle's evidence rules. Add `source/slang/slang-check-modifier.cpp` to `watched_paths` to close this. | — |
| cacbfb570aa9 | rejected-out-of-scope | Emitted-HLSL field shapes are owned by `docs/generated/design/target-pipelines/hlsl.md` and `docs/generated/design/pipeline/04c-layout-ir.md`; the AST-reference family contract makes `## Nodes` "a single table" (`docs/generated/design/_meta/prompts/_common.md:99`) and forbids code blocks in `## Notable nodes` (`:118`), so a before/after emitted-code example has no place on this page. | — |
| bf4747525daf | fixed | `source/slang/slang-parser.cpp:10789-10790` maps both `row_major` and `column_major` to the *HLSL* classes; `source/slang/slang-ast-modifier.h:660-677` declares the two `GLSL*` classes with the inversion comment, and a tree-wide grep finds no construction site for either (only the two allow-list `case` labels in `slang-check-modifier.cpp`). | replaced the unreachable "GLSL dialect" framing with the fact that no parse path constructs the two classes, set their Grammar cells to `(none)`, and added a short paragraph after the table |
| f15bd5a1e013 | fixed | `source/slang/core.meta.slang:4699-4713` carries the attribute's own worked example, including the line `t.load(); // error: result of '[NoDiscard]' function is discarded.` and the accepted `let loaded = t.load();`; bundle test `nodiscard-rejects-discarded-result.slang` pins `E30059` and `nodiscard-attribute-used-result.slang` the accepted form. | cited error `30059` and its message in the `NoDiscardAttribute` row, contrasting the discarded call with the accepted bound one |
| fd362de57127 | fixed | `source/slang/slang-parser.cpp:10768-10769` registers `__ref` → `RefModifier` and `__constref` → `BorrowModifier`; no `ref` or `borrow` entry exists in the modifier table, and the only `"ref"` keyword in the parser is the property `ref` accessor at `:4721`. | quoted `__ref` / `__constref` in the two Summary cells and noted the un-prefixed forms are not parameter modifiers |
| 7ec70fffdcc0 | fixed | The page's own `### Visibility modifiers and language version` subsection already states the default is decided by `ModuleDecl::languageVersion` / `defaultVisibility`; the table row previously claimed a single global default. | replaced "(default in modern Slang)" on the `InternalModifier` row with a per-module statement and a link to that subsection |
| bcad4ad9f150 | fixed | The document carried `### Work-graph node attributes` twice, under `## Nodes` and under `## Notable nodes`, so both rendered to `#work-graph-node-attributes`. | renamed the prose heading to "Work-graph node attribute spellings", leaving the table heading's anchor (the one existing citations resolve to) unchanged |
