Shader packs: a stray #endif and an #if left open are warnings, as in Iris

Iris 1.11.7 draws a program with a stray `#endif` (it logs "#endif without
#if") and one whose `#if` stays open to the end of the file (seen with
probe packs written for this). Horizon reported both as errors and skipped
the program: with Pegasus v0.5 every gbuffers program (terrain and water had
none), with Bloop its composite6. Both are now warnings: the stray `#endif`
is ignored, the open `#if` reads on to the end.

Fixes #7167

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Arslan ArmanulyandClaude Opus 5.5 committed 2026-11-02 17:20:40 +05:00
1 parent fbb17c980e
commit 8cf2eaf48d
2 files changed
+33 -2

No files matched your search

+1 -1
View File
@@ -1139,7 +1139,7 @@ fn diagnostics(pp: &Preprocessed) -> Vec<String> {
located(pp, &pp.diagnostics)
}
/// `pp`'s warnings (conditions read as false), located.
/// `pp`'s warnings (conditions read as false, unbalanced conditionals), located.
fn warnings(pp: &Preprocessed) -> Vec<String> {
located(pp, &pp.warnings)
}
+32 -1
View File
@@ -70,8 +70,12 @@ pub fn preprocess(pack: &Pack, path: &str, macros: &Macros) -> Preprocessed {
texts: HashMap::new(),
};
run.file(path, 0, Origin::default());
// Iris 1.11.7 draws a program whose `#if` stays open to its end: a warning, as there.
if run.conditionals.open() {
run.diagnose(Origin::default(), "`#if` without `#endif`");
run.out.warnings.push(Diagnostic {
origin: Origin::default(),
message: "`#if` without `#endif`: read to the end of the file".into(),
});
}
run.out.code = run.code.join("\n");
run.out
@@ -169,6 +173,11 @@ impl Run<'_> {
Err(e) if e.ends_with("read as false") => {
return self.out.warnings.push(Diagnostic { origin, message: e });
}
// Iris 1.11.7 logs a stray `#endif` and draws the program: it is ignored.
Err(e) if word == "endif" => {
let message = format!("{e}: ignored");
return self.out.warnings.push(Diagnostic { origin, message });
}
Err(e) => return self.diagnose(origin, &e),
Ok(true) => return,
Ok(false) if !self.conditionals.active() => return,
@@ -411,6 +420,28 @@ mod tests {
assert_eq!(messages, ["#error live", "unknown directive `#bogus`"]);
}
/// A stray `#endif` and an `#if` left open are warnings, as in Iris 1.11.7 (which draws such
/// a program): the `#endif` is ignored, the open `#if` reads on to the end of the file.
#[test]
fn unbalanced_conditionals_warn_and_the_code_goes_on() {
let p = run(&[(
"program/final.fsh",
"#version 330\n#ifdef NEVER\nfloat a;\n#else\nfloat b;\n#endif\n#endif\n\
#if 1\nfloat c;\n",
)]);
assert!(p.diagnostics.is_empty(), "{:?}", p.diagnostics);
let warnings: Vec<&str> = p.warnings.iter().map(|w| w.message.as_str()).collect();
assert_eq!(
warnings,
[
"`#endif` without `#if`: ignored",
"`#if` without `#endif`: read to the end of the file"
]
);
let code: Vec<&str> = code_lines(&p).iter().map(|(c, _)| *c).collect();
assert_eq!(code, ["float b;", "float c;"]);
}
/// A condition that can't be evaluated is a warning and reads as false; the code goes on.
#[test]
fn bad_conditions_warn_and_read_false() {