From 906c664a654bac100ac17786d62c72b3fc2753c5 Mon Sep 17 00:00:00 2001 From: bigmerge Date: Sat, 15 Aug 2026 21:47:32 -0500 Subject: [PATCH] compiler: a missing import is an error, not an empty string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit import "../../NOPE/does_not_exist.el" compiled CLEANLY — exit 0, empty stderr, and a program silently missing everything it imported. resolve_imports did `fs_read(src_path)` and used the result without checking. fs_read returns "" both for "file is empty" and "file does not exist", so a typo, a moved file, or a relative path resolved from the wrong working directory all produced a successful build of nothing. It caused a real wrong conclusion during test-framework work: a bisection run from a subdirectory where ../../runtime/ did not resolve produced ELEVEN consecutive "successful" compiles that had included no runtime at all, and the results were believed before anyone noticed. Missing dependency, confident success — the same shape as a test suite reporting pass for tests that never ran, and as a benchmark reporting 0us because the optimiser deleted the loop. fs_exists separates the two cases, so a legitimately empty file still resolves to "" and is fine. A path that does not exist now prints the resolved path and exits 1, which is what build scripts check. Verified: - bad import: exit 1 (was 0), message names the resolved path - elc-cli.el still compiles, self-hosting fixpoint byte-identical - neuron's full soul amalgam regeneration: exit 0, 405ms, output byte-identical at 1,270,212 bytes --- lang/el-compiler/src/compiler.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lang/el-compiler/src/compiler.el b/lang/el-compiler/src/compiler.el index b9647bb..14c3ccd 100644 --- a/lang/el-compiler/src/compiler.el +++ b/lang/el-compiler/src/compiler.el @@ -419,6 +419,22 @@ fn resolve_imports(src_path: String) -> String { if !str_eq(already, "") { return "" } state_set(seen_key, "1") + // A missing file must be a hard error, never an empty string. + // + // fs_read returns "" both for "file is empty" and "file does not exist", and + // this function used the value without distinguishing them. So a broken + // import path — a typo, a moved file, a relative path resolved from the + // wrong working directory — compiled CLEANLY: exit 0, empty stderr, and a + // program silently missing everything it imported. Observed 2026-08-15: + // eleven consecutive "successful" compiles that had included no runtime at + // all, and a wrong conclusion drawn from them before anyone noticed. + // + // Missing dependency, confident success. fs_exists separates the two cases, + // so a genuinely empty file still resolves to "" and is fine. + if !fs_exists(src_path) { + println("elc: cannot resolve import: " + src_path) + exit_program(1) + } let source: String = fs_read(src_path) let dir: String = dirname_of(src_path) let lines: [String] = str_split(source, "\n")