Guard the sharpening kernel against WGSL reserved keywords
The fused-fragment check in lib.rs cannot see a detail pass: it is a separate shader composed at a resolution compose() never knows. The kernel's own test now scans the block the composer wrapped, with comments stripped so prose about the keyword cannot fail a test about the code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -799,9 +799,8 @@ mod tests {
|
||||
// source rather than at the operation that wrote it, and this body
|
||||
// reaches for exactly that word.
|
||||
//
|
||||
// Not the full reserved list; the words a convolution would plausibly
|
||||
// pick for a local.
|
||||
// The same list `no_fragment_declares_a_wgsl_reserved_keyword` uses,
|
||||
// Not the full reserved list; the words a kernel would plausibly pick
|
||||
// for a local. The same list `no_fragment_declares_a_wgsl_reserved_keyword` uses,
|
||||
// kept identical on purpose: two lists that drift apart would let a
|
||||
// word be safe in one stage and not in the other, which is the sort of
|
||||
// difference nobody discovers until a shader fails to compile.
|
||||
@@ -813,18 +812,33 @@ mod tests {
|
||||
];
|
||||
|
||||
for pass in chain_at(&sharpening(100.0, 2.0), RenderScale::full((512, 512))).passes {
|
||||
// Only what this operation wrote. The composer's own preamble
|
||||
// declares `var output` and `let coord`, which naga accepts and
|
||||
// which are not this test's business.
|
||||
let body = pass
|
||||
// Only what this operation wrote — the block the composer wraps
|
||||
// the body in. Its preamble declares `var output` and its tail
|
||||
// writes through it, and neither is this test's business; scanning
|
||||
// the whole file would fail on generated code nobody here can fix.
|
||||
let block = pass
|
||||
.source
|
||||
.rsplit_once(" {\n")
|
||||
.expect("the operation's block")
|
||||
.expect("the operation's block opens")
|
||||
.1;
|
||||
let body = block
|
||||
.split_once("\n }\n")
|
||||
.map_or(block, |(inside, _)| inside);
|
||||
|
||||
// Comments are not declarations, and the kernel deliberately names
|
||||
// `target` in one to say why it does not use it. Stripping them
|
||||
// keeps this on the code, so that editing the prose can never fail
|
||||
// a test about what compiles.
|
||||
let code: Vec<&str> = body
|
||||
.lines()
|
||||
.filter(|l| !l.trim_start().starts_with("//"))
|
||||
.collect();
|
||||
let code = code.join("\n");
|
||||
|
||||
for keyword in RESERVED {
|
||||
for form in [format!("let {keyword} "), format!("var {keyword} ")] {
|
||||
assert!(
|
||||
!body.contains(&form),
|
||||
!code.contains(&form),
|
||||
"{} declares `{keyword}`, which is a WGSL reserved keyword",
|
||||
pass.label
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user