Skip to content

本体をどこにも持たない宣言を診断で断つ - #200

Merged
routersys merged 11 commits into
mainfrom
dev/ComputeWeave.BodilessDeclarationRefusal
Sep 5, 2026
Merged

本体をどこにも持たない宣言を診断で断つ#200
routersys merged 11 commits into
mainfrom
dev/ComputeWeave.BodilessDeclarationRefusal

Conversation

@routersys

@routersys routersys commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary / 概要

本体をどこにも持たない宣言を取り込むと、生成される HLSL に書くものがありません。extern の宣言がその場合で、C# は警告としか言いません。取り込むメソッドと局所関数は本体の無い宣言としてそのまま書き出され、シェーダーコンパイラが利用者の書いていない符号を名指しします。取り込む構築子と入口は生成器を終了させ、そのコンパイル単位の全てのシェーダーの記述子を捨てます。

CMPW0127CMPWD2D0099 を足し、宣言の3つの種それぞれの本体を正規化する visit から報告します。宣言には空の本体を与え、書き換えはそこで終わらせません。

Linked issue / 関連する課題

Closes #183

Kind / 種別

  • Bug fix / 不具合修正
  • Analyzer or generator / アナライザーまたはジェネレーター

Behavior change / 挙動の変更

本体の無い宣言を取り込む入力が、シェーダーコンパイラの失敗や生成器の終了ではなく、その宣言を名指しする誤りになります。診断を1件足すので、CMPW は111件、CMPWD2D は99件になります。

本体を持つ宣言の生成物は変わりません。下の全数の突き合わせがその測定です。公開APIの署名は変わりません。

Verification / 検証

dotnet build ComputeWeave.sln -t:Rebuild -c Release -p:Platform=x64 -p:EmitCompilerGeneratedFiles=true
dotnet build tests/ComputeWeave.Tests.SourceGenerators/ComputeWeave.Tests.SourceGenerators.csproj -c Release -p:Platform=x64
dotnet tests/ComputeWeave.Tests.SourceGenerators/bin/x64/Release/net10.0/ComputeWeave.Tests.SourceGenerators.dll

土台は 9cf26d40 です。解全体の建て直しは警告0件、誤り0件でした。土台の欄も同じ機械で測った値で、CI の報告ではありません。

スイート 土台 この枝 スキップ
ComputeWeave.Tests.SourceGenerators 500 517 0
ComputeWeave.D2D1.Tests.SourceGenerators 220 223 0
ComputeWeave.D2D1.Tests.AssemblyLevelAttributes 4 4 0
ComputeWeave.Tests.Internals 1085 1085 0
ComputeWeave.D2D1.Tests 204 204 8
ComputeWeave.Tests 4154 4154 52

土台もこの枝も失敗0件です。足した試験は20本で、計算側の生成器へ17本、Direct2D 側へ3本です。増えた分だけ合計が動いています。

CIも通りました。「ビルドとテスト」が回した6つのスイートは、総数が上の表と同じで、いずれも失敗0件です。CIはハードウェアのアダプターを持たない機械なので、判定しない試験の数だけが手元と違います。「デバイス消失のテスト」と「変更範囲の判定と確認」と「文書の検査」も成功しています。

手元で走らせていないのはデバッグレイヤーだけです。バリア、資源の状態、キューの選択、相互運用のいずれにも触れておらず、本体を持つ宣言の生成物も変わらないためです。

Adapter and driver tested / 試したアダプターとドライバー: Intel(R) Iris(R) Xe Graphics, 32.0.101.7085

族を全数で測り、断りの境界も測りました

本体をどこにも持たない宣言を、宣言を読む6つの探索と局所関数の2つを合わせて9形で掃きました。修正の前は9形すべてが欠陥です。

修正前 修正後
静的メソッドを本文から取り込む CMPW0046 CMPW0127
インスタンスメソッドを本文から取り込む CMPW0046 CMPW0127
静的メソッドを初期化子から取り込む CMPW0046 CMPW0127
シェーダー自身のメソッドを呼ぶ CMPW0046 CMPW0127
局所関数をシェーダーの本文に書く CMPW0046 CMPW0127
局所関数を取り込むメソッドの中に書く CMPW0046 CMPW0127
構築子を本文から取り込む 生成器が終了 CMPW0127
構築子を初期化子から取り込む 生成器が終了 CMPW0127
入口を extern で書く 生成器が終了 CMPW0127

CMPW0046 は断りではなく、HLSL コンパイラが生成された符号に対して失敗したという報告です。修正後はどの形も報告が CMPW0127 の1件だけで、異常終了は1件もありません。

断るかどうかは、その宣言が生成される HLSL へ書き出されるかどうかと一致します。呼ばれていなくても書き出される宣言は断り、書き出されない宣言は今までどおり触りません。

書き出されるか 報告
シェーダー自身のメソッド、呼ばれない 書き出される CMPW0127
局所関数、呼ばれない 書き出される CMPW0127
外の構造体のメソッド、呼ばれない 書き出されない 無し
外の静的クラスのメソッド、呼ばれない 書き出されない 無し
外の構造体の構築子、使われない 書き出されない 無し

シェーダー自身のメソッドと局所関数は、呼ばれなくても生成される HLSL に前方宣言と定義の両方が出ます。生成された文字列で確かめました。外の型のメンバーは、シェーダーが届いたときにだけ取り込まれます。上の5形はいずれも試験で固定してあります。

生成物を全数で突き合わせました

解全体を -p:EmitCompilerGeneratedFiles=true で建て直し、書き出された file を突き合わせています。比べたのは同じ作業ツリーの2点で、実装を入れた状態と、実装の2つの file だけを土台の内容へ戻した状態です。各回の建ての前に生成物の folder を消しています。-t:Rebuild はそこを消さないので、消さずに歩くと前の建ての file を相手側と突き合わせることになります。

数えたもの
どちらの側にも在る file 1049
内容が1バイト違わない file 1047
内容が動いた file 2
片側にしか無い file 0

動いた2件は Direct2D の記述子で、同じコミットで2回建てても同じ2件が動きます。動くのは埋め込まれた符号の先頭にある検査値だけです。戻した側でも解全体が誤り0件で建ちますので、本体の無い宣言はこの木の中に1件もありません。

変異試験

実装をコミットしてから、実装の2つの file を土台の内容へ戻して測りました。この修正は報告と、空の本体を与えることの2つでできているので、変異も2つに分けています。

壊した箇所 計算側の生成器 Direct2D の生成器
報告を外す 合計517、失敗11 合計223、失敗3
空の本体を外す 合計517、失敗3 合計223、失敗1

報告を外すと、断りを見る14本がすべて名指しで落ちます。空の本体を外すと、修正前に生成器が終了していた4形だけが落ちます。計算側の3本は構築子の2形と入口で、Direct2D 側の1本は構築子です。2つの変異が別の集合を落とすので、どちらの半分も守るものを持っています。

この変異は試験の穴を1つ見つけました。Direct2D 側の行を最初に足したときは、取り込むメソッドと入口の2本でした。空の本体を外す変異で1本も落ちなかったので調べたところ、Direct2D の入口はそもそも終了せず、終了するのは構築子の取り込みでした。構築子の行を足して、この変異が名指しで落とすことを確かめています。

Notes for the reviewer / 査読者への注記

断つ判断

本体は生成される HLSL に書き出すものそのものですから、持たない宣言は書くものがありません。C# が extern を許すので、利用者の側からは正しい C# として届きます。書き出せない以上、通す形はありません。

置き場

報告は、宣言の3つの種それぞれの本体を正規化する visit から出します。宣言を読む6つの探索、つまり4つの取り込みと2つの生成器の入口は、いずれもその3箇所のどれかを通ります。

探索の側へ置く形も採れますが、同じ規則を6回書くことになるうえ、それでは足りません。シェーダー自身のメソッドと呼ばれない局所関数は、探索を経ずに書き出されるためです。3つの visit は、書き出される宣言がすべて通る唯一の場所です。

終了させずに空の本体を与える理由

生成器が終了すると、その生成器の出力はコンパイル単位ごと捨てられます。利用者へ届くのは、生成された型が見つからないという無関係な誤りの束で、直すべき宣言はどこにも出てきません。それがこの報告の置き換えようとしている失敗そのものですから、そこで終わらせては意味がありません。報告は誤りなので、空の本体が書き出したものがシェーダーコンパイラへ届くことはありません。

利用者が報告を抑止した場合は届きます。そのとき構築子は既定の値を返すので、C# と違う値を黙って計算します。これは断りのあとに既定の値を返す CMPW0120 と同じ露出で、この木で既に確立された形です。抑止は誤りに対して明示的に行うものなので、そこまでを設計の対象にしていません。

本体を正規化する補助は、もともと「常に波括弧の本体を返す」と述べていました。本体を持たない宣言に対してそれが成り立っていなかったので、述べているとおりにしただけです。

この族に入らないもの

実装部を持たない部分メソッドは C# 自身が断ちます。アクセシビリティを持つものは誤りになり、持たないものは消去されて呼び出しが解決しません。どちらも生成器へ届かないことを測ってあります。部分宣言のうち実装部を持つものは、その実装部が読まれるので、この変更の影響を受けません。

利用者が定義した演算子は、本体を持つかどうかに関わらず CMPW0115 が先に断ちます。二項演算子と変換演算子で測りました。宣言の取り込みへ届かないので、この規則の対象になりませんし、報告が2つ出ることもありません。

Direct2D の経路

書き換え器は2つの生成器で共有されていますから、報告も両方へ掛かります。識別子は生成器ごとに別なので、記述子は両側に要ります。Direct2D 側の入口は計算側と別の符号を通るので、独立した行を置きました。

前提が崩れたときの退避

枝ごと戻せます。診断を1件外すことになるので、未出荷の記録と README の件数6箇所も一緒に戻ります。前提が崩れる筋は、本体の無い宣言から意味のある HLSL を書き出せるようになる場合ですが、書くものが無いという性質は言語の側の話なので、崩れるとすれば C# の側です。

測っていないこと

利用者の符号がこの形を何箇所含むかは分かりません。この木の中には1件もありませんでした。

extern 以外に本体をどこにも持てない宣言があるかは、C# の仕様を全数で当たったわけではありません。掃いたのは extern と部分宣言と演算子の3つです。

報告が1件だけであることを固定しているのは計算側だけです。Direct2D 側の補助は識別子を重複除去してから比べるので、同じ原因が2回報告されても通ります。報告を出すのは共有の書き換え器なので、Direct2D 側だけで重複が起きるには、あちらに固有の二重訪問が要ります。それは測っていません。

Checklist / 確認

  • The pull request is one logical change, with no unrelated refactoring or formatting. / 一つの論理的な変更にまとまっており、無関係な整理や整形を含まない。
  • Every commit builds on its own. / 各コミットが単独でビルドできる。
  • Implementation changes and their verification tests are separate commits. / 実装の変更と検証テストを別のコミットに分けた。
  • No commit already merged into the default branch or referenced by a release tag was rewritten. / 既定ブランチへ入った、またはリリースタグが指すコミットを書き換えていない。
  • The change follows the implementation pattern already established in the subsystem. / 変更は、その部分で既に確立された実装パターンに従っている。
  • Existing documentation comments were preserved. / 既存のドキュメントコメントを維持した。
  • No silent fallback behavior or compatibility shim was introduced. / 暗黙の代替動作や互換性のための繕いを持ち込んでいない。
  • No unrelated dependency was updated. / 無関係な依存関係を更新していない。
  • A new diagnostic was added, so its release record and the counts the documents state were updated. / 診断を追加したので、リリース記録と文書が述べる件数を更新した。
  • If a file inherited from upstream changed, the divergence ledger in CONTRIBUTING.md was updated, or the change was judged not to be a divergence. / 上流から受け継いだファイルを変更した場合、CONTRIBUTING.md の乖離台帳を更新したか、乖離ではないと判断した。

If this touches a guarded area / 慎重を要する箇所に触れる場合

  • Tests exercise the guarded behavior itself, and I confirmed they fail when that behavior is deliberately broken. / 試験が守るべき挙動そのものを動かしており、その挙動を意図的に壊すと落ちることを確認した。
  • For public API or generated descriptor changes, the compatibility, deterministic-generation or golden-data checks of the affected subsystem were run. / 公開APIまたは生成される記述子を変えた場合、該当部分の互換性、生成の決定性、または基準データの検査を走らせた。

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

PRレビュー / PR review

変更 14 ファイル、コミット 11 件。 / 14 files, 11 commits.

検証の要否 / Verification required

以下を走らせ、失敗した試験の名前と失敗の様子を変更前と突き合わせてください。総数だけで判断しないでください。
Run the following and compare the names and failure modes against the same suites before your change. Do not judge by totals alone.

dotnet build ComputeWeave.sln -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests.SourceGenerators/ComputeWeave.Tests.SourceGenerators.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests.Internals/ComputeWeave.Tests.Internals.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests/ComputeWeave.Tests.csproj -c Release -p:Platform=x64

ビルドエラーを出す診断を変えた場合は、アナライザーの試験に加えて解全体の検証が要ります。
If a diagnostic that produces build errors changed, verify the complete solution as well.

慎重を要する箇所 / Guarded areas touched

  • 寿命と破棄 / lifetime and disposal
    • src/ComputeWeave.D2D1.SourceGenerators/AnalyzerReleases.Unshipped.md
    • src/ComputeWeave.SourceGeneration.Hlsl/Extensions/SyntaxNodeExtensions.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/HlslSourceRewriter.Diagnostics.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/ShaderSourceRewriter.cs
    • src/ComputeWeave.SourceGenerators/AnalyzerReleases.Unshipped.md
  • 記述子と診断 / descriptors and diagnostics
    • src/ComputeWeave.D2D1.SourceGenerators/AnalyzerReleases.Unshipped.md
    • src/ComputeWeave.D2D1.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/HlslSourceRewriter.Diagnostics.cs
    • src/ComputeWeave.SourceGenerators/AnalyzerReleases.Unshipped.md
    • src/ComputeWeave.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs

寿命の追跡と危険の追跡は別々の保証です。一方を保っても他方が保たれるとは限りません。
Lifetime tracking and hazard tracking are separate guarantees; preserving one does not preserve the other.

公開APIまたは生成される記述子を変えた場合は、該当部分の互換性、生成の決定性、基準データの検査を走らせてください。
For public API or generated descriptor changes, run the compatibility, deterministic-generation or golden-data checks of the affected subsystem.

指摘 / Findings

  • 実装と検証テストが同じコミットに入っています。分けてください。 / Implementation and tests share a commit; split them.
    - 07d248ad Merge remote-tracking branch 'origin/main' into dev/ComputeWeave.BodilessDeclarationRefusal

確認できた点 / Confirmed

  • 概要が書かれています。 / A summary is present.
  • 検証の結果が書かれています。 / Verification results are present.
  • 関連する課題が示されています。 / A linked issue is referenced.

これは自動の確認で、査読の代わりにはなりません。指摘は判断の材料であって、従う義務はありません。
This is an automated check, not a substitute for review. Findings are input to a decision, not obligations.

@routersys routersys added bug Something isn't working / 不具合が起きている analyzer or generator Analyzer or generator / アナライザーまたはジェネレーター labels Sep 5, 2026
@routersys
routersys merged commit 04827ac into main Sep 5, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

analyzer or generator Analyzer or generator / アナライザーまたはジェネレーター bug Something isn't working / 不具合が起きている

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 取り込む宣言の本体と修飾子が、C# の意味どおりに書き出されない

1 participant