ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Slang 生成式设计文档的审查实践:03-semantic-check 审查报告的机制、发现与源码佐证

2026/9/18 22:56:41 拓冰建站 浏览量
Slang 生成式设计文档的审查实践:03-semantic-check 审查报告的机制、发现与源码佐证 Slang 生成式设计文档的审查实践03-semantic-check 审查报告的机制、发现与源码佐证【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang本文以 Slang 仓库中的一份真实文档审查报告docs/generated/design/_meta/reviews/pipeline/03-semantic-check.md.review.md为主体完整拆解其元数据、审查流程与四条 minor 级发现的证据链并结合 语义检查设计文档 与source/slang/下的 checker 源码说明“生成式文档如何用可验证的方式保持与源码一致”这一工程方法的完整闭环。读完你会掌握如何解读审查报告 front matter 中的 digest、checklist 与 severity 语义如何按发现定位源码证据以及如何复现这套“prompt 约束生成 → 审查比对源码 → 修订回写”的文档质量体系。这份审查报告在文档体系中的位置Slang 的设计文档分两层docs/design/下是人工维护的原始设计稿如 semantic-checking.md、decl-refs.md、interfaces.mddocs/generated/design/下是按固定模板从源码生成的结构化文档。每个生成页都带有 front matter 声明generated: true、source_commit与watched_paths_digest提示“自动生成、可能漂移、勿手改”。本报告正是这套体系的质量闸门产物它不是讲“语义检查怎么写”的技术文档而是一份针对目标文档 pipeline/03-semantic-check.md 的事实核对清单。报告结论先行页面结构完整、所有链接可解析、绝大多数实现性陈述与记录 commit 处的源码一致剩余 4 条 minor 发现两处源码归属描述失准、一节超出“仅概述”的契约、binding 修饰符的门控描述把一个门控过度推广到四个诊断、结尾一句虚构了并不存在的 errored 声明状态。见报告 Summary 一节报告文件 03-semantic-check.md.review.md 与目标文档一一对应存放在docs/generated/design/_meta/reviews/下按目标文档的子目录镜像组织pipeline/、architecture/、ir-reference/等。Front matter自描述的审查元数据报告开头的 YAML front matter 是机器可读的“审查身份证”字段及含义如下以报告实际内容为准字段报告中的值含义review_reporttrue标记本文件是审查报告而非普通设计文档reviewer_modelgpt-5.6-sol执行审查的模型标识保证结果可追溯、可复现reviewed_at2026-08-04T08:18:5000:00审查执行时间target_docpipeline/03-semantic-check.md被审查的目标文档相对docs/generated/design/target_doc_source_commit/source_commit53b76e6d...审查时目标文档与源码共同的基线 commit。所有行号引用都锚定在这个 committarget_doc_watched_paths_digesta244dfa1...目标文档“监视路径”即它所引用的 checker 源文件内容的摘要值用于判断文档是否已过期checklist六项 pass/partial见下表finding_count4发现总数severity_breakdowncritical: 0 / major: 0 / minor: 4 / nit: 0严重度分布checklist六项的逐项结论检查项结果对应的人工验证方式factual_accuracypartial抽查文档中的实现性陈述是否与源码一致F-001、F-003、F-004 都落在这里cross_referencespass文档内每个相对链接在基线 commit 下都能解析且生成的文档引用都是 manifest 条目completenesspartial必填小节是否齐全F-002 属于此维度章节存在但违反了 prompt 约定的篇幅契约style_consistencypass行文与模板风格一致source_alignmentpartial文档与源码的实际对齐程度front_matter_validitypass目标文档自身 front matter 合法且重算 digest 与记录值一致值得强调的是 digest 机制报告明确记录“recomputed the watched-path digest; it matchesa244dfa1...”。这意味着审查者不是直接信任 front matter 里写的摘要而是独立重算了目标文档所监视的全部源文件的摘要并比对——digest 一致才谈得上“文档陈述与这批源码对齐”。这是防止“文档声称基于某版本源码实际引用的是另一版本”的关键防线。审查流程报告实际执行了哪些核对报告 “Items checked” 一节列出了五步实证工作每一步都是可复核的动作而非结论宣称Front matter 与 digest校验目标文档 front matter重算 watched-path digest 并比对成功。链接解析在基线 commit53b76e6d3009b8e6434d41573524c7ce5c499d23下验证每一个相对链接目标并确认文档引用的生成文档都是 manifest.yaml 中的正式条目。行号引用核对验证全部11 处行号引用共覆盖15 个被引用的源码行号——每一处都确认指向了其所声明的符号或声明。事实抽查抽查 25 项以上事实陈述覆盖 checker 编排、延迟函数体解析、约束求解、witness 查找、继承线性化、可微性合成、shader 检查与诊断恢复。完备性确认每个必填小节都在且每个被监视的slang-check-*.cpp文件都至少在文档中被提及一次。第 5 条对应的是生成 prompt 中的质量清单。pipeline-03-semantic-check.md该页的生成 prompt规定每个被监视的slang-check-*.cpp文件必须至少提及一次、不得复述与 Slang 无关的类型系统理论、文档长度小于 32 KB并逐条列出了必须包含的小节## Inputs and outputs、## SemanticsVisitor、## Two-pass interaction with the parser、## Name lookup and DeclRef、## Generic specialization and constraints、## Synthesizing implicit code、## Failure modes等。审查报告的 checklist 结果本质上是逐条回勾这份契约的结果。发现 F-001源码文件职责归属写错位置目标文档## SemanticsVisitor下的“Files and responsibilities”表原稿第 65–68 行区域。错误表中有两行把源码职责安错了文件slang-check-inheritance.cpp被描述为拥有“member visibility成员可见性”slang-check-resolve-val.cpp被描述为“validate substitutions校验替换”。实际情况已在当前源码验证slang-check-inheritance.cpp 实现的是继承与 extension facet 的计算。第 139–207 行是SharedSemanticsContext::getInheritanceInfo(Type*, ...)它维护m_mapTypeToInheritanceInfo缓存、用isComputing标记进行中的条目以打破继承计算环并通过ioSkippedIncompleteFacet出参把被跳过的“进行中的祖先”向上传播。可见性过滤实际发生在表达式/重载检查一侧slang-check-expr.cpp 第 1136–1275 行、slang-check-overload.cpp 第 272–278 行区域。slang-check-resolve-val.cpp 文件头注释第 2–3 行写得很直白Logic for resolving/simplifying Types and DeclRefs.。前 59 行实现Type::createCanonicalType、_resolveAsDeclRef、SubtypeWitness的解析与开销ConversionCost等——它做的是解析并规范化Type、DeclRef与 witness 值而不是校验替换。修订建议报告原文从 inheritance 行中删去“member visibility”把slang-check-resolve-val.cpp描述为“resolving/canonicalizingType,DeclRef, and witness values”。现状对照仓库当前版本的 03-semantic-check.md该表已按建议改写——inheritance 行现在写 “Inheritance and extension lookup; facet computation”resolve-val 行写 “Resolves and canonicalizesType,DeclRef, and witness values”并且表中每个文件都附带一条“该文件自身会发出的诊断示例”如E30815、E31202使每一行都成为可以写测试验证的具体论断。发现 F-002通用特化一节超出“仅概述”契约位置目标文档## Generic specialization and constraints一节原稿第 101–247 行区域。错误生成 prompt pipeline-03-semantic-check.md 对该节的明确要求是## Generic specialization and constraints—overview only; the deep details live in../../design/interfaces.md.即只允许给出架构级概述深入细节应留给 interfaces.md。但原稿在这一节用约 140 行展开了约束求解器的回退机制solver 失败后按约束线性重推失败点、关联类型约束的统一表示associatedtype A : IBar、__constraint A : IBar都被记录为外层 interface 的GenericTypeConstraintDecl、继承缓存的“善意环”处理__constraint A B使T.A/T.B互为基类、用ioSkippedIncompleteFacet收集被跳过的不完整 facet 且不缓存部分结果、泛型推断失败载荷GenericArgumentInferenceFailure的 6 种Kind及其诊断映射表、以及可微性合成内部[Differentiable]如何被改写成extension __func_as_type(f) : IForwardDifferentiable...。修订建议报告原文把该节压缩为简短的架构概述细节保留对 interfaces.md 与相关源文件slang-check-constraint.cpp、slang-check-conformance.cpp、slang-check-resolve-val.cpp的链接。值得注意的是报告 “No-issues notes” 同时肯定了这一节的内容本身是源码支持的——约束求解、继承环、可微性与泛型入口点的论断都能对得上源码。也就是说 F-002 不是事实错误而是篇幅契约违规生成文档体系里“这一页讲多深”是由 prompt 约束的审查会把超纲当作独立缺陷处理。发现 F-003把“一个门控”过度推广到“四个诊断”位置目标文档## Shader-specific checks中 “Ignored binding modifiers on entry-point parameters” 条目原稿第 329–338 行区域。错误原文说[[vk::binding(...)]]、[[vk::push_constant]]、register()、packoffset()这四种在入口点参数上被忽略的 binding 修饰符全部由_allTargetsSupportVkBindingOnEntryPointParameters与isVkBindingCompatibleEntryPointParameterType两个谓词门控。实际情况在 slang-check-shader.cpp 第 2331–2366 行审查基线 commit 处supportsVkBindingOnParameter只在GLSLBindingAttribute分支里生效随后[[vk::push_constant]]、register()、packoffset()各有一个无条件的诊断分支——只要出现在入口点参数上就报告Diagnostics::UnhandledModOnEntryPointParameterE38010不查目标是否真的支持。为什么这个区分重要[[vk::binding(...)]]只有在“所有链接目标都不支持入口点参数上的 vk binding”或“参数类型与 vk binding 不兼容”时才会被真正丢弃此时报告E38010才不算误报而另外三个修饰符在此上下文中总是会被丢弃因此无条件诊断。把门控写错会让读者以为四个诊断都依赖目标能力查询从而误解-target组合下哪些警告会消失。现状当前版本文档已修正为准确表述03-semantic-check.mdOnly the[[vk::binding(...)]]case is gated — by_allTargetsSupportVkBindingOnEntryPointParameters(line 1580) over all of the linkages targets and byisVkBindingCompatibleEntryPointParameterType(line 920) ...[[vk::push_constant]],register(), andpackoffset()are diagnosed unconditionally when found on an entry-point parameter.发现 F-004虚构了一个不存在的 “errored 声明状态”位置目标文档## Failure modes结尾原稿第 383–385 行区域。错误原稿声称每个声明“either fully checked or marked errored要么完全检查完要么被标记为 errored”。审查结论是checker 里不存在这样的替代状态。源码证据slang-check-decl.cpp 中checkModule的主干注释把机制写得非常清楚——语义检查的全部目标就是让模块内所有声明推进到DeclCheckState::DefinitionChecked并最终到CapabilityChecked且采用逐状态推进的迭代方式而非深递归// 源码注释slang-check-decl.cpp 第 5192–5206 行附近 // The entire goal of semantic checking is to get all of the // declarations in the module up to DeclCheckState::DefinitionChecked. // ... // Instead, we would rather do more breadth-first checking, // where everything gets checked up to state 1, 2, ... // before anything gets too far ahead. DeclCheckState states[] { DeclCheckState::ScopesWired, DeclCheckState::ReadyForReference, DeclCheckState::ReadyForLookup, DeclCheckState::ReadyForConformances, DeclCheckState::DefinitionChecked, DeclCheckState::CapabilityChecked, };也就是说错误不是用一种特殊的“errored 声明状态”表示的而是诊断经DiagnosticSink报告AST 里就地替换为ErrorType类型的节点或合成的errorExpr检查继续向前。声明状态机本身定义于 slang-ast-support-types.h只有上述正常序列。修订建议报告原文改为“checkModule把声明驱动到CapabilityChecked恢复通过记录诊断并在需要处替换 error 类型/表达式来表达”。当前版本文档03-semantic-check.md已按此修正“there is no separate errored state, so recovery is expressed as diagnostics plus error types / expressions substituted in place.”No-issues notes通过项同样是证据报告没有只列问题还单列了 “No-issues notes”说明哪些容易出错的地方特意核对过且没有问题全部行号引用都指向了所声明的符号或声明而不是附近的无关代码延迟UnparsedStmt处理与 parser 回调确实对应maybeParseStmt/parseUnparsedStmt这是 Slang “parser 与 checker 两阶段交互”的核心机制详见 parsing.md约束求解、继承环、可微性与泛型入口点的详细论断都有源码支撑——即便 F-002 认定该节超纲其内容本身仍是准确的。这类“无问题备注”的价值在于后续读者或下一轮审查无需重新怀疑这些区域可以把注意力集中到真正的缺陷上。从单份报告看整套审查流水线把报告放回它所在的目录结构可以看清这套文档质量体系的全部参与方均位于 docs/generated/design/_meta/文件角色manifest.yaml生成文档的正式条目清单审查时用来确认“被引用的生成文档都是 manifest 条目”prompts/每页文档的生成 prompt规定必填小节、引用文件与篇幅契约如“overview only”是 completeness 检查的基准regenerate.py / regenerate.md依据源码重新生成文档的脚本与说明review-state.json各文档审查状态汇总freshness.json / doc-gap-state.json文档新鲜度与缺口跟踪schema/front matter 等结构的 schemareviews/按目标文档镜像存放的审查报告本文件即其一工作流可以概括为prompt 约束生成 → 生成页绑定source_commit与watched_paths_digest→ 审查者在同一基线上重算 digest、解析链接、核对行号引用、抽查事实 → 输出带 severity 分级与逐条证据的报告 → 生成页按建议修订并重新生成。本报告中四个 minor 发现里F-001、F-003、F-004 在仓库当前版本的 03-semantic-check.md 中均能验证到已按建议落地的修订措辞正是这条闭环生效的直接证据。背景速览被审查的语义检查器长什么样为了让读者理解上述发现指向什么简要勾勒目标文档所描述的 checker 结构细节以 03-semantic-check.md 为准入口checkTranslationUnitslang-check.cpp前端解析完成后每个TranslationUnitRequest调用一次SemanticsVisitor家族通过SemanticsContext共享状态slang-check-impl.h。文件分工slang-check-decl.cpp声明检查E30200、slang-check-expr.cpp表达式E30011、slang-check-stmt.cpp语句E30003、slang-check-type.cppE30060、slang-check-overload.cpp重载E40018、slang-check-conformance.cpp接口一致性与默认 witness 合成、slang-check-conversion.cppE30523、slang-check-inheritance.cpp继承/extension facetE30815、slang-check-modifier.cpp修饰符互斥E31202、slang-check-constraint.cpp泛型约束求解E30433、slang-check-resolve-val.cpp类型/DeclRef/witness 的解析与规范化自身不发出诊断、slang-check-shader.cpp入口点检查E38007。两阶段交互函数体先留作UnparsedStmtchecker 到达时经parseUnparsedStmt触发二次解析parser 会回调 checker 消歧等 token——函数体内不存在干净的 parse/check 边界。恢复策略未解析的声明换成ErrorType重载失败返回合成errorExpr单点错误不级联。审查报告的每一条发现本质上都是在核对这张“文件 × 职责 × 诊断码”映射表的准确性——这正是生成式设计文档最容易漂移、也最值得自动化核对的部分。要点这份报告示范了生成式技术文档的验收方式digest 重算、链接解析、行号引用逐条核对、事实抽查、完备性回勾 prompt 契约全部动作可复现。四条 minor 发现分别落在“源码归属”“篇幅契约”“门控范围”“状态机事实”四类高频漂移点上且每条都给出可点击核对的源码证据如 slang-check-resolve-val.cpp 的文件头注释、slang-check-decl.cpp 的状态序列。对维护者的直接启示写“文件 X 负责 Y”这类陈述前先读文件头注释与入口函数描述诊断门控时逐分支确认哪个分支真的受目标能力谓词保护描述恢复机制时以源码中实际存在的状态枚举为准不要用“直觉上应该有”的错误态。【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考