#!/usr/bin/env node import { execFile } from "node:child_process"; import { existsSync } from "node:fs"; import { access, chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { resolve } from "node:path"; import { createAggregateAssert, describeFailure, finishAggregateAssert } from "../scripts/aggregate-assert.mjs"; const assert = createAggregateAssert(); if (process.env.ZERO_NATIVE_TEST_SANDBOX !== "1" && process.env.ZERO_NATIVE_TEST_ALLOW_LOCAL !== "1") { console.error("conformance emits native test artifacts; run `pnpm run conformance` for Vercel Sandbox execution or set ZERO_NATIVE_TEST_ALLOW_LOCAL=1 to opt into local artifacts."); process.exit(1); } const execMaxBuffer = 16 * 1024 * 1024; const zero = resolve(process.env.ZERO_BIN || (existsSync(".zero/bin/zero") ? ".zero/bin/zero" : "bin/zero")); const outDir = process.env.ZERO_CONFORMANCE_OUT_DIR || ".zero/conformance"; const canRunLinuxMuslX64 = process.platform === "linux" && process.arch === "x64"; const runnableDirectTarget = process.platform === "darwin" && process.arch === "arm64" ? "darwin-arm64" : process.platform === "linux" && process.arch === "x64" ? "linux-musl-x64" : null; const checkTimeoutMs = Number(process.env.ZERO_CHECK_TIMEOUT_MS ?? 2000); function parsePositiveInt(value, fallback) { const parsed = Number.parseInt(value ?? "", 10); return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; } const defaultCheckJobs = 1; const checkJobs = parsePositiveInt(process.env.ZERO_CONFORMANCE_CHECK_JOBS, defaultCheckJobs); function runnableExeArgs(input, out) { if (!runnableDirectTarget) return null; return ["build", "--emit", "exe", "--target", runnableDirectTarget, compilerInputPath(input), "--out", out]; } await mkdir(outDir, { recursive: true }); await mkdir(`${outDir}/check-cache`, { recursive: true }); function execFileAsync(file, args = [], options = {}) { return new Promise((resolve, reject) => { const normalizedArgs = file === zero ? normalizeZeroCompilerArgs(args) : args; execFile(file, normalizedArgs, { maxBuffer: execMaxBuffer, ...options }, (error, stdout, stderr) => { if (error) { error.stdout = stdout; error.stderr = stderr; reject(error); return; } resolve({ stdout, stderr }); }); }); } function tomlQuote(value) { return JSON.stringify(String(value)); } function tomlArray(values) { return `[${values.map(tomlQuote).join(", ")}]`; } function appendManifestFields(lines, object, order) { for (const key of order) { if (!(key in object)) continue; const value = object[key]; if (Array.isArray(value)) lines.push(`${key} = ${tomlArray(value)}`); else if (typeof value === "boolean") lines.push(`${key} = ${value ? "true" : "false"}`); else lines.push(`${key} = ${tomlQuote(value)}`); } } function manifestToml(manifest) { const lines = ["[package]"]; appendManifestFields(lines, manifest.package ?? {}, ["name", "version", "license"]); for (const [targetName, target] of Object.entries(manifest.targets ?? {})) { lines.push("", `[targets.${targetName}]`); appendManifestFields(lines, target, ["kind", "main", "graph", "defaultTarget", "devTarget", "releaseProfile"]); } if (manifest.repositoryGraph) { lines.push("", "[repositoryGraph]"); appendManifestFields(lines, manifest.repositoryGraph, ["compilerInput"]); } for (const sectionName of ["deps", "dependencies"]) { if (!manifest[sectionName]) continue; lines.push("", `[${sectionName}]`); for (const [name, value] of Object.entries(manifest[sectionName])) { if (typeof value === "string") lines.push(`${name} = ${tomlQuote(value)}`); } for (const [name, value] of Object.entries(manifest[sectionName])) { if (typeof value === "string") continue; lines.push("", `[${sectionName}.${name}]`); appendManifestFields(lines, value, ["path", "version", "targets", "target"]); } } for (const [name, lib] of Object.entries(manifest.c?.libs ?? {})) { lines.push("", `[c.libs.${name}]`); appendManifestFields(lines, lib, ["headers", "include", "lib", "link", "mode", "pkg_config", "pkgConfig"]); } return `${lines.join("\n").replace(/\n{3,}/g, "\n\n")}\n`; } async function writeZeroToml(root, manifest) { await writeFile(`${root}/zero.toml`, manifestToml(manifest)); } function graphSidecarPath(sourcePath) { if (!sourcePath.endsWith(".0")) throw new Error(`${sourcePath}: expected a .0 projection path`); return `${sourcePath.slice(0, -2)}.graph`; } const compilerInputCommands = new Set(["check", "build", "run", "test", "size", "mem", "doc", "dev", "time", "fix"]); const compilerInputValueFlags = new Set(["--backend", "--emit", "--filter", "--out", "--profile", "--release", "--target"]); const abiInputSubcommands = new Set(["check", "dump"]); function compilerInputPath(inputPath) { if (typeof inputPath !== "string" || !inputPath.endsWith(".0")) return inputPath; const graphPath = graphSidecarPath(inputPath); if (!existsSync(graphPath)) { throw new Error(`${inputPath}: compiler command requires graph input; missing graph sidecar ${graphPath}`); } return graphPath; } function normalizeZeroCompilerArgs(args) { if (!Array.isArray(args)) return args; const isCompilerInputCommand = compilerInputCommands.has(args[0]); const isAbiInputCommand = args[0] === "abi" && abiInputSubcommands.has(args[1]); if (!isCompilerInputCommand && !isAbiInputCommand) return args; let afterProgramArgs = false; let skipOptionValue = false; return args.map((arg) => { if (afterProgramArgs) return arg; if (arg === "--") afterProgramArgs = true; if (skipOptionValue) { skipOptionValue = false; return arg; } if (compilerInputValueFlags.has(arg)) { skipOptionValue = true; return arg; } return afterProgramArgs ? arg : compilerInputPath(arg); }); } async function writeGraphFixture(sourcePath, source) { await writeFile(sourcePath, source); const graphPath = graphSidecarPath(sourcePath); await execFileAsync(zero, ["import", "--format", "binary", "--out", graphPath, sourcePath]); return graphPath; } async function importGraphFixtureFailure(sourcePath) { const result = await execFileAsync(zero, ["import", "--json", "--format", "binary", "--out", graphSidecarPath(sourcePath), sourcePath]).catch((error) => error); assert.notEqual(result.code, 0); return JSON.parse(result.stdout); } async function writeImportFailureFixture(sourcePath, source) { await writeFile(sourcePath, source); return importGraphFixtureFailure(sourcePath); } async function importPackageGraph(root) { await execFileAsync(zero, ["import", root]); } function isolatedCacheEnv(workerIndex) { return { ...process.env, ZERO_CACHE_DIR: `${outDir}/check-cache/worker-${workerIndex}`, }; } async function mapLimit(items, limit, callback) { const results = new Array(items.length); let next = 0; const workerCount = Math.min(Math.max(1, limit), Math.max(1, items.length)); async function worker(workerIndex) { await mkdir(`${outDir}/check-cache/worker-${workerIndex}`, { recursive: true }); for (;;) { const index = next++; if (index >= items.length) return; try { results[index] = await callback(items[index], index, workerIndex); } catch (error) { const item = Array.isArray(items[index]) ? items[index][0] : items[index]; results[index] = { error }; assert.fail(`parallel conformance item failed: ${item}\n${describeFailure(error)}`); } } } await Promise.all(Array.from({ length: workerCount }, (_, index) => worker(index))); return results; } async function checkFixtureParallel(fixture, workerIndex) { const options = checkJobs > 1 ? { env: isolatedCacheEnv(workerIndex) } : {}; const result = await execFileAsync(zero, ["check", fixture], options).catch((error) => error); assert.equal(result.code ?? 0, 0, `${fixture} should check cleanly\n${result.stderr ?? ""}`); } async function checkFailureFixtureParallel(fixture, code, workerIndex) { const options = checkJobs > 1 ? { env: isolatedCacheEnv(workerIndex) } : {}; const result = await execFileAsync(zero, ["check", fixture], options).catch((error) => error); assert.notEqual(result.code, 0); assert.match(result.stderr, code); } async function fileExists(path) { try { await access(path); return true; } catch { return false; } } function assertRepositoryGraphNativeCheck(body, sourceProjectionState = "clean", options = {}) { const graphHirToMirUsed = options.graphHirToMirUsed === false ? false : true; const compilerInputReady = body.targetReadiness?.ok === true && graphHirToMirUsed; assert.equal(body.graphCompiler.input, "repository-graph-store"); assert.equal(body.graphCompiler.graphStoreLoaded, true); assert.equal(body.graphCompiler.sourceProjectionRequiredForCompilerInput, false); assert.equal(body.graphCompiler.sourceProjectionState, sourceProjectionState); assert.equal(body.graphCompiler.graphNativeCheckerUsed, true); assert.equal(body.graphCompiler.graphHirToMirUsed, graphHirToMirUsed); assert.equal(body.graphCompiler.unsupportedGraphFacts.count, 0); assert.equal(body.graphCompiler.resolution.ok, true); assert.equal(body.graphCompiler.resolution.state, "resolved-graph-facts"); assert.equal(body.graphCompiler.checking.ok, true); assert.equal(body.graphCompiler.checking.state, "checked-graph-readiness-facts"); assert.equal(body.graphCompiler.checking.scope, "resolution-package-target-and-graph-mir-readiness"); assert.equal(body.graphCompiler.checking.semanticDiagnosticsEnforced, false); assert.equal(body.graphCompiler.checking.semanticDiagnosticsAuthority, "stored-typed-graph-facts"); assert.equal(body.graphCompiler.checking.authority, "ProgramGraphStore"); assert.equal(body.graphCompiler.checking.sourceTextAuthority, false); assert.equal(body.graphCompiler.semanticFacts.state, "typed-facts"); assert.equal(body.graphCompiler.semanticFacts.ok, true); const targetReady = body.targetReadiness?.ok === true; assert.equal(body.graphCompiler.defaultReadiness.compilerInputReady, compilerInputReady); assert.equal(body.graphCompiler.defaultReadiness.claim, compilerInputReady ? "ready-for-repository-graph-input" : "blocked"); assert.equal(body.graphCompiler.defaultReadiness.sourceFreeCompile, compilerInputReady); assert.equal(body.graphCompiler.defaultReadiness.sourceProjectionRequired, false); assert.equal(body.graphCompiler.defaultReadiness.sourceProjectionState, sourceProjectionState); assert.equal(body.graphCompiler.defaultReadiness.graphMir.used, graphHirToMirUsed); assert.equal(Object.hasOwn(body.graphCompiler.defaultReadiness, "fallback"), false); assert.equal(body.graphCompiler.defaultReadiness.performance.validationInLoad, true); assert.equal(body.graphCompiler.defaultReadiness.cacheInvalidation.parserArtifactsInKey, false); assert(body.graphCompiler.defaultReadiness.cacheInvalidation.keyedBy.includes("nodeHashes")); assert(body.graphCompiler.defaultReadiness.cacheInvalidation.keyedBy.includes("symbolFacts")); assert(body.graphCompiler.defaultReadiness.cacheInvalidation.keyedBy.includes("modulePaths")); assert(body.graphCompiler.defaultReadiness.cacheInvalidation.keyedBy.includes("importPaths")); assert.equal(body.graphCompiler.defaultReadiness.targetReadinessOk, targetReady); assert.equal(body.compileTime.deterministic, true); assert.equal(body.targetReadiness.languageOk, true); assert.equal(body.safetyFacts.schemaVersion, 1); } function assertSourceGraph(body, artifact, moduleIdentity, lowering = "typed-program-graph-mir", canonicalSource = false, sourceProjectionState = undefined) { assert.equal(body.graph.artifact, artifact); assert.equal(body.graph.canonicalSource, canonicalSource); assert.equal(body.graph.moduleIdentity, moduleIdentity); assert.match(body.graph.graphHash, /^graph:[0-9a-f]{16}$/); assert.equal(body.graph.lowering, lowering); if (sourceProjectionState !== undefined) assert.equal(body.graph.sourceProjectionState, sourceProjectionState); } const programGraphParseTreeKeys = new Map(); function assertProgramGraphCompilerInput(body, artifact) { assert(body.compilerCaches.every((cache) => cache.sourceKind === "program-graph" && cache.graphHash === body.graph.graphHash)); assert(body.compilerCaches.every((cache) => cache.parserArtifactsInKey === false)); const caches = new Map(body.compilerCaches.map((cache) => [cache.name, cache])); const assertCacheInputs = (name, includes, excludes = []) => { const cache = caches.get(name); assert(cache, `missing compiler cache ${name}`); for (const key of includes) assert(cache.graphKeyInputs.includes(key), `${name} cache key inputs should include ${key}`); for (const key of excludes) assert(!cache.graphKeyInputs.includes(key), `${name} cache key inputs should not include ${key}`); }; assertCacheInputs("parseTree", ["graphHash", "nodeHashes", "importPaths", "compilerVersion", "packageDependencies"], ["sourceFiles", "targetFacts", "profile"]); assertCacheInputs("interface", ["graphHash", "modulePaths", "symbolFacts", "importGraph"], ["targetFacts", "profile", "compilerVersion", "packageDependencies"]); assertCacheInputs("checkedBody", ["graphHash", "importPaths", "targetFacts", "compilerVersion", "packageDependencies"], ["sourceFiles", "profile"]); assertCacheInputs("specialization", ["graphHash", "importPaths", "targetFacts", "profile", "compilerVersion", "packageDependencies"], ["sourceFiles"]); if (body.graph.lowering === "mapped-final-mir") { assertCacheInputs("mappedFinalMir", ["graphHash", "importPaths", "targetFacts", "compilerVersion", "packageDependencies", "emitKind", "backend"], ["sourceFiles", "profile"]); const mappedMirCache = caches.get("mappedFinalMir"); assert.match(mappedMirCache.path, /\.zero\/cache\/native\/mir-[0-9a-f]+\.zmir$/); assert.equal(mappedMirCache.memoryMapped, true); assert.equal(mappedMirCache.borrowedStorage, true); assert.equal(mappedMirCache.byteLength > 0, true); assert.equal(body.incrementalInvalidation.graphInput.mappedFinalMir.path, mappedMirCache.path); assert.equal(body.incrementalInvalidation.graphInput.mappedFinalMir.memoryMapped, true); assert.equal(body.incrementalInvalidation.graphInput.mappedFinalMir.borrowedStorage, true); } assertCacheInputs("emittedObject", ["graphHash", "importPaths", "targetFacts", "profile", "compilerVersion", "packageDependencies"], ["sourceFiles"]); const parseTreeCache = caches.get("parseTree"); assert.equal(parseTreeCache.invalidatesOn, "ProgramGraph input"); if (programGraphParseTreeKeys.has(artifact)) assert.equal(parseTreeCache.key, programGraphParseTreeKeys.get(artifact)); else programGraphParseTreeKeys.set(artifact, parseTreeCache.key); assert.equal(body.incrementalInvalidation.sourceKind, "program-graph"); assert.equal(body.incrementalInvalidation.graphInput.artifact, artifact); assert.equal(body.incrementalInvalidation.graphInput.graphHash, body.graph.graphHash); assert.equal(body.incrementalInvalidation.graphInput.parserArtifactsInKey, false); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("graphHash")); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("nodeHashes")); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("typeFacts")); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("symbolFacts")); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("modulePaths")); assert(body.incrementalInvalidation.graphInput.keyedBy.includes("importPaths")); assert.equal(body.incrementalInvalidation.changedInputs.graphArtifact, artifact); assert.equal(body.incrementalInvalidation.interfaceFingerprints.sourceKind, "program-graph"); assert.equal(body.incrementalInvalidation.interfaceFingerprints.graphHash, body.graph.graphHash); } function assertLlvmPhiPredecessors(ir) { const predecessors = new Map(); const phiEdges = []; let functionIndex = -1; let current = "-1:entry"; const scoped = (label) => `${functionIndex}:${label}`; for (const line of ir.split("\n")) { if (line.startsWith("define ")) { functionIndex++; current = scoped("entry"); continue; } const label = line.match(/^(L[0-9]+):$/); if (label) { current = scoped(label[1]); continue; } const branch = line.match(/^ br (?:label %(L[0-9]+)|i1 [^,]+, label %(L[0-9]+), label %(L[0-9]+))$/); if (branch) { for (const target of branch.slice(1).filter(Boolean)) { const key = scoped(target); if (!predecessors.has(key)) predecessors.set(key, new Set()); predecessors.get(key).add(current); } continue; } if (!line.includes(" = phi ")) continue; for (const match of line.matchAll(/\[[^\]]+, %(L[0-9]+)\]/g)) { phiEdges.push({ block: current, predecessor: scoped(match[1]) }); } } for (const edge of phiEdges) { assert( predecessors.get(edge.block)?.has(edge.predecessor), `LLVM phi predecessor ${edge.predecessor} must branch to ${edge.block}`, ); } } async function buildLlvmIrFixture(fixture, name) { const outPath = `${outDir}/${name}.ll`; const build = await execFileAsync(zero, [ "build", "--json", "--emit", "llvm-ir", "--backend", "llvm", fixture, "--out", outPath, ]); const body = JSON.parse(build.stdout); assert.equal(body.emit, "llvm-ir"); assert.equal(body.compiler, "zero-c-llvm-ir"); assert.equal(body.generatedCBytes, 0); return readFile(outPath, "utf8"); } async function assertLlvmHostExitCode(fixture, name, expectedCode) { const readiness = await execFileAsync(zero, ["check", "--json", "--backend", "llvm", fixture]).catch((error) => error); if (readiness.code) return; const readinessBody = JSON.parse(readiness.stdout); if (!readinessBody.targetReadiness?.ok) return; const out = `${outDir}/${name}`; const build = await execFileAsync(zero, ["build", "--json", "--backend", "llvm", fixture, "--out", out]); const body = JSON.parse(build.stdout); assert.equal(body.emit, "exe"); assert.equal(body.objectBackend.backendFamily, "llvm"); const run = await execFileAsync(out, []).catch((error) => error); assert.equal(run.code ?? 0, expectedCode); assert.equal(run.signal ?? null, null); } async function assertBoundsTrap(fixture, name) { const out = `${outDir}/${name}`; const build = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", "linux-musl-x64", fixture, "--out", out]).catch((error) => error); if (build.code) { const body = JSON.parse(build.stdout); assert.equal(body.diagnostics?.[0]?.code, "BLD004"); return; } const body = JSON.parse(build.stdout); assert.equal(body.generatedCBytes, 0); if (!canRunLinuxMuslX64) return; const failedRun = await execFileAsync(out, []).catch((error) => error); assert.notEqual(failedRun.code ?? (failedRun.signal ? 1 : 0), 0); if (failedRun.stderr) assert.match(failedRun.stderr, /zero bounds check failed|trap: index out of bounds/); } async function assertDirectRuntimeOrUnsupported(fixture, name, expected) { const out = `${outDir}/${name}`; const build = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", "linux-musl-x64", fixture, "--out", out]).catch((error) => error); if (build.code) { const body = JSON.parse(build.stdout); assert.equal(body.diagnostics?.[0]?.code, "BLD004"); return; } const body = JSON.parse(build.stdout); assert.equal(body.generatedCBytes, 0); assert.equal(body.legacy, false); if (!canRunLinuxMuslX64) return; const run = await execFileAsync(out, expected.args ?? [], expected.env ? { env: { ...process.env, ...expected.env } } : {}).catch((error) => error); if (run.code || run.signal) return; if (expected.stdout instanceof RegExp) assert.match(run.stdout, expected.stdout); else assert.equal(run.stdout, expected.stdout); if (expected.stderr !== undefined) assert.equal(run.stderr, expected.stderr); if (expected.file) assert.equal(await readFile(`${outDir}/${expected.file.name}`, "utf8"), expected.file.text); } async function assertDirectRuntimeRequired(fixture, name, expected) { const target = runnableDirectTarget ?? "linux-musl-x64"; const out = `${outDir}/${name}`; const build = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", target, fixture, "--out", out]); const body = JSON.parse(build.stdout); assert.equal(body.generatedCBytes, 0); assert.equal(body.legacy, false); if (!runnableDirectTarget) return; const run = await execFileAsync(out, expected.args ?? [], expected.env ? { env: { ...process.env, ...expected.env } } : {}); if (expected.stdout instanceof RegExp) assert.match(run.stdout, expected.stdout); else assert.equal(run.stdout, expected.stdout); if (expected.stderr !== undefined) assert.equal(run.stderr, expected.stderr); } async function assertCommonRuntimeOrUnsupported(fixture, name, expected) { const target = runnableDirectTarget ?? "linux-musl-x64"; const out = `${outDir}/${name}`; const build = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", target, fixture, "--out", out]).catch((error) => error); if (build.code) { const body = JSON.parse(build.stdout); assert.equal(body.diagnostics?.[0]?.code, "BLD004"); return; } const body = JSON.parse(build.stdout); assert.equal(body.generatedCBytes, 0); assert.equal(body.legacy, false); if (!runnableDirectTarget) return; const run = await execFileAsync(out, expected.args ?? [], expected.env ? { env: { ...process.env, ...expected.env } } : {}).catch((error) => error); assert.equal(run.code ?? 0, 0); assert.equal(run.signal ?? null, null); if (expected.stdout instanceof RegExp) assert.match(run.stdout, expected.stdout); else assert.equal(run.stdout, expected.stdout); if (expected.stderr !== undefined) assert.equal(run.stderr, expected.stderr); if (expected.file) assert.equal(await readFile(`${outDir}/${expected.file.name}`, "utf8"), expected.file.text); } async function assertCheckTimeoutOrDiagnostic(fixture, expectedCodes) { const result = await execFileAsync(zero, ["check", "--json", fixture], { timeout: checkTimeoutMs }).catch((error) => error); if (result.killed || result.signal) { assert.equal(result.killed, true); return { timedOut: true }; } assert.notEqual(result.code, 0); const body = JSON.parse(result.stdout); const code = body.diagnostics?.[0]?.code; assert(expectedCodes.includes(code), `expected one of ${expectedCodes.join(", ")}, got ${code}`); return { timedOut: false, code }; } async function assertElf64Object(path, exportedName) { const bytes = await readFile(path); assert.equal(bytes[0], 0x7f); assert.equal(bytes[1], 0x45); assert.equal(bytes[2], 0x4c); assert.equal(bytes[3], 0x46); assert.equal(bytes[4], 2); assert.equal(bytes[5], 1); assert.equal(bytes.readUInt16LE(16), 1); assert.equal(bytes.readUInt16LE(18), 62); const shoff = Number(bytes.readBigUInt64LE(40)); const shentsize = bytes.readUInt16LE(58); const shnum = bytes.readUInt16LE(60); const shstrndx = bytes.readUInt16LE(62); const cstr = (offset) => { let end = offset; while (end < bytes.length && bytes[end] !== 0) end++; return bytes.toString("utf8", offset, end); }; const shstrHeader = shoff + shstrndx * shentsize; const shstrOffset = Number(bytes.readBigUInt64LE(shstrHeader + 24)); const sections = new Map(); for (let i = 0; i < shnum; i++) { const header = shoff + i * shentsize; sections.set(cstr(shstrOffset + bytes.readUInt32LE(header)), { index: i, offset: Number(bytes.readBigUInt64LE(header + 24)), size: Number(bytes.readBigUInt64LE(header + 32)), link: bytes.readUInt32LE(header + 40), entsize: Number(bytes.readBigUInt64LE(header + 56)), }); } assert(sections.get(".text")?.size > 0); const symtab = sections.get(".symtab"); assert(symtab); const strtab = [...sections.values()].find((section) => section.index === symtab.link); assert(strtab); let sawExport = false; for (let offset = symtab.offset; offset < symtab.offset + symtab.size; offset += symtab.entsize) { const name = cstr(strtab.offset + bytes.readUInt32LE(offset)); const info = bytes[offset + 4]; const shndx = bytes.readUInt16LE(offset + 6); const size = Number(bytes.readBigUInt64LE(offset + 16)); if (name === exportedName && info === 0x12 && shndx === sections.get(".text").index && size > 0) sawExport = true; } assert(sawExport); return { bytes, sections }; } async function assertElfAarch64Object(path, exportedName) { const bytes = await readFile(path); assert.equal(bytes[0], 0x7f); assert.equal(bytes[1], 0x45); assert.equal(bytes[2], 0x4c); assert.equal(bytes[3], 0x46); assert.equal(bytes[4], 2); assert.equal(bytes[5], 1); assert.equal(bytes.readUInt16LE(16), 1); assert.equal(bytes.readUInt16LE(18), 183); assert(bytes.includes(Buffer.concat([Buffer.from(exportedName), Buffer.from([0])]))); return bytes; } function hasAarch64Instruction(bytes, expected) { for (let offset = 0; offset + 4 <= bytes.length; offset++) { if (bytes.readUInt32LE(offset) === expected) return true; } return false; } function countAarch64InstructionSequence(bytes, expected) { let count = 0; for (let offset = 0; offset + expected.length * 4 <= bytes.length; offset++) { let matched = true; for (let index = 0; index < expected.length; index++) { if (bytes.readUInt32LE(offset + index * 4) !== expected[index]) { matched = false; break; } } if (matched) count++; } return count; } function aarch64SpLoad(reg, offset, wide) { const scale = wide ? 8 : 4; assert.equal(offset % scale, 0); return ((wide ? 0xf9400000 : 0xb9400000) + ((offset / scale) << 10) + (31 << 5) + reg) >>> 0; } function aarch64ByteViewReloadSequence(count) { const sequence = []; for (let index = 0; index < count; index++) { sequence.push(aarch64SpLoad(index * 2, index * 16, true)); sequence.push(aarch64SpLoad(index * 2 + 1, index * 16 + 8, false)); } return sequence; } function hasAarch64CondBranch(bytes, cond) { for (let offset = 0; offset + 4 <= bytes.length; offset++) { const instruction = bytes.readUInt32LE(offset); if ((instruction & 0xff000010) === 0x54000000 && (instruction & 0xf) === cond) return true; } return false; } async function assertElf64Executable(path) { const bytes = await readFile(path); assert.equal(bytes[0], 0x7f); assert.equal(bytes[1], 0x45); assert.equal(bytes[2], 0x4c); assert.equal(bytes[3], 0x46); assert.equal(bytes[4], 2); assert.equal(bytes[5], 1); assert.equal(bytes.readUInt16LE(16), 2); assert.equal(bytes.readUInt16LE(18), 62); assert(Number(bytes.readBigUInt64LE(24)) > 0); assert.equal(Number(bytes.readBigUInt64LE(32)), 64); assert.equal(bytes.readUInt16LE(54), 56); assert.equal(bytes.readUInt16LE(56), 1); const phoff = Number(bytes.readBigUInt64LE(32)); assert.equal(bytes.readUInt32LE(phoff), 1); assert.equal(bytes.readUInt32LE(phoff + 4), 5); assert(Number(bytes.readBigUInt64LE(phoff + 32)) > 0); assert.equal(Number(bytes.readBigUInt64LE(phoff + 32)), Number(bytes.readBigUInt64LE(phoff + 40))); } async function assertElfAarch64Executable(path) { const bytes = await readFile(path); assert.equal(bytes[0], 0x7f); assert.equal(bytes[1], 0x45); assert.equal(bytes[2], 0x4c); assert.equal(bytes[3], 0x46); assert.equal(bytes[4], 2); assert.equal(bytes[5], 1); assert.equal(bytes.readUInt16LE(16), 2); assert.equal(bytes.readUInt16LE(18), 183); assert.equal(bytes.readUInt16LE(54), 56); assert.equal(bytes.readUInt16LE(56), 1); assert(bytes.includes(Buffer.from([0x40, 0x05, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6]))); assert(bytes.includes(Buffer.from([0xa8, 0x0b, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4]))); } async function assertMachOArm64Object(path, exportedName) { const bytes = await readFile(path); assert.equal(bytes.readUInt32LE(0), 0xfeedfacf); assert.equal(bytes.readUInt32LE(4), 0x0100000c); assert.equal(bytes.readUInt32LE(12), 1); assert(bytes.includes(Buffer.concat([Buffer.from(`_${exportedName}`), Buffer.from([0])]))); return bytes; } async function assertMachOX64Object(path, exportedName) { const bytes = await readFile(path); assert.equal(bytes.readUInt32LE(0), 0xfeedfacf); assert.equal(bytes.readUInt32LE(4), 0x01000007); assert.equal(bytes.readUInt32LE(12), 1); assert(bytes.includes(Buffer.concat([Buffer.from(`_${exportedName}`), Buffer.from([0])]))); return bytes; } function assertX64SliceBoundsTrapBytes(bytes) { assert(bytes.includes(Buffer.from([0x0f, 0x86]))); assert(bytes.includes(Buffer.from([0x0f, 0x0b]))); } function assertX64U16RecordFieldBytes(bytes) { assert(bytes.includes(Buffer.from([0x0f, 0xb7]))); assert(bytes.includes(Buffer.from([0x66, 0x89]))); } function isRexW(byte) { return (byte & 0xf8) === 0x48; } function hasX64MovMemoryToR64(bytes) { for (let i = 0; i + 2 < bytes.length; i++) { if (!isRexW(bytes[i]) || bytes[i + 1] !== 0x8b) continue; const mod = bytes[i + 2] >> 6; if (mod !== 3) return true; } return false; } function hasX64MovR64ToMemory(bytes) { for (let i = 0; i + 2 < bytes.length; i++) { if (!isRexW(bytes[i]) || bytes[i + 1] !== 0x89) continue; const mod = bytes[i + 2] >> 6; if (mod !== 3) return true; } return false; } function hasX64CmpR64(bytes) { for (let i = 0; i + 2 < bytes.length; i++) { if (!isRexW(bytes[i]) || bytes[i + 1] !== 0x39) continue; const mod = bytes[i + 2] >> 6; if (mod === 3) return true; } return false; } async function assertMachOArm64Executable(path) { const bytes = await readFile(path); assert.equal(bytes.readUInt32LE(0), 0xfeedfacf); assert.equal(bytes.readUInt32LE(4), 0x0100000c); assert.equal(bytes.readUInt32LE(12), 2); const ncmds = bytes.readUInt32LE(16); let sawUuid = false; for (let offset = 32, i = 0; i < ncmds; i++) { const cmd = bytes.readUInt32LE(offset); const cmdsize = bytes.readUInt32LE(offset + 4); assert(cmdsize >= 8); assert(offset + cmdsize <= bytes.length); if (cmd === 0x1b) { assert.equal(cmdsize, 24); assert(!bytes.subarray(offset + 8, offset + 24).every((byte) => byte === 0)); sawUuid = true; } offset += cmdsize; } assert(sawUuid); assert(bytes.includes(Buffer.from("/usr/lib/dyld"))); assert(bytes.includes(Buffer.from("/usr/lib/libSystem.B.dylib"))); assert(bytes.includes(Buffer.from("zero-direct"))); return bytes; } async function assertCoffX64Object(path, exportedName) { const bytes = await readFile(path); assert.equal(bytes.readUInt16LE(0), 0x8664); assert(bytes.readUInt16LE(2) >= 1); assert(bytes.readUInt32LE(8) > 0); assert(bytes.includes(Buffer.concat([Buffer.from(exportedName), Buffer.from([0])]))); return bytes; } async function assertPeCoffX64Executable(path) { const bytes = await readFile(path); assert.equal(bytes[0], 0x4d); assert.equal(bytes[1], 0x5a); const peOffset = bytes.readUInt32LE(0x3c); assert.equal(bytes.toString("ascii", peOffset, peOffset + 4), "PE\u0000\u0000"); assert.equal(bytes.readUInt16LE(peOffset + 4), 0x8664); assert.equal(bytes.readUInt16LE(peOffset + 24), 0x20b); assert.equal(bytes.readUInt16LE(peOffset + 92), 3); assert(bytes.includes(Buffer.from("KERNEL32.dll"))); assert(bytes.includes(Buffer.from("ExitProcess"))); assert(bytes.includes(Buffer.from("WriteFile"))); return bytes; } const passCheckFixtures = [ "conformance/run/pass/hello.0", "conformance/native/pass/params.0", "conformance/native/pass/shape.0", "conformance/native/pass/mutref-shape-param.0", "conformance/native/pass/mutref-shape-param-nested.0", "conformance/native/pass/primitive-stdlib.0", "conformance/native/pass/break-continue.0", "conformance/native/pass/nested-break-continue.0", "conformance/native/pass/untyped-literal-adoption.0", "conformance/native/pass/for-range.0", "conformance/native/pass/choice-payload-reference-return.0", "conformance/native/pass/choice-match-payload-reference-origin.0", "conformance/native/pass/choice-match-payload-return-origin.0", "conformance/native/pass/null-maybe.0", "conformance/native/pass/maybe-local-null-init-return.0", "conformance/native/pass/meta-typed-target-type.0", "conformance/native/pass/std-args.0", "conformance/native/pass/std-env.0", "conformance/native/pass/std-hosted-cli.0", "conformance/native/pass/std-fs.0", "conformance/native/pass/std-fs-bytes.0", "conformance/native/pass/std-fs-read-chunks.0", "conformance/native/pass/frame-large-locals.0", "conformance/native/pass/frame-limit-boundary.0", "conformance/native/pass/frame-split-helpers.0", "conformance/native/pass/fixed-buf-alloc-local.0", "conformance/native/pass/std-fs-resource.0", "conformance/native/pass/std-fs-readall.0", "conformance/native/pass/std-fs-polish.0", "conformance/native/pass/std-fs-breadth.0", "conformance/native/pass/std-fs-file-helpers.0", "conformance/native/pass/std-pty-child.0", "conformance/native/pass/std-math-breadth.0", "conformance/native/pass/std-numeric-random-time.0", "conformance/native/pass/std-regex.0", "conformance/native/pass/std-unicode.0", "conformance/native/pass/std-inet.0", "conformance/native/pass/std-time-rfc3339.0", "conformance/native/pass/std-io-lines.0", "conformance/native/pass/std-path-io-breadth.0", "conformance/native/pass/std-str-breadth.0", "conformance/native/pass/std-testing-log.0", "conformance/native/pass/std-term-ansi.0", "conformance/native/pass/std-testing-helpers-test.0", "conformance/native/pass/std-path-helper-name-collision.0", "conformance/native/pass/std-net-http-breadth.0", "conformance/native/pass/std-http-metadata-neutral.0", "conformance/native/pass/std-http-fetch.0", "conformance/native/pass/std-http-errors.0", "conformance/native/pass/std-http-response-helpers.0", "conformance/native/pass/std-http-text-html-response-helpers.0", "conformance/native/pass/std-http-redirect-response-helpers.0", "conformance/native/pass/std-http-api-helpers.0", "conformance/native/pass/std-http-cors-helpers.0", "conformance/native/pass/std-http-auth-helpers.0", "conformance/native/pass/std-data-formats.0", "conformance/native/pass/std-csv.0", "conformance/native/pass/std-diag.0", "conformance/native/pass/std-codec-json-url.0", "conformance/native/pass/std-json-cursors.0", "conformance/native/pass/std-json-bytes.0", "conformance/native/pass/std-json-inline-bytes.0", "conformance/native/pass/std-json-duplicate-keys.0", "conformance/native/pass/std-json-allocator-capacity.0", "conformance/native/pass/std-platform-basics.0", "conformance/native/pass/std-mem-arrays.0", "conformance/native/pass/std-mem-generic-items.0", "conformance/native/pass/std-mem-field-items.0", "conformance/native/pass/std-mem-byte-field-copy.0", "conformance/native/pass/std-mem-bool-copy-items.0", "conformance/native/pass/std-mem-u64-contains.0", "conformance/native/pass/std-mem-u64-copy-items.0", "conformance/native/pass/std-mem-local-u64-copy-items.0", "conformance/native/pass/array-repeat-literal.0", "conformance/native/pass/array-repeat-record-field.0", "conformance/native/pass/integer-widths.0", "conformance/native/pass/std-codec-widths.0", "conformance/native/pass/std-crypto-hmac32.0", "conformance/native/pass/std-crypto-sha256.0", "conformance/native/pass/parse-integers.0", "conformance/native/pass/explicit-casts.0", "conformance/native/pass/float-char-casts.0", "conformance/native/pass/radix-suffix-literals.0", "conformance/native/pass/char-literals.0", "conformance/native/pass/float-primitives.0", "conformance/native/pass/wrapping-saturating-arithmetic.0", "conformance/native/pass/maybe-guard-branch-restore.0", "conformance/native/pass/maybe-guard-negated-conjunction.0", "conformance/native/pass/maybe-guard-scalar-match.0", "conformance/native/pass/maybe-guard-short-circuit-match.0", "conformance/native/pass/maybe-guard-static-index-literals.0", "conformance/native/pass/maybe-guard-variant-match-after.0", "conformance/native/pass/maybe-guard-variant-guard-side-effect.0", "conformance/native/pass/match-scalar-guards.0", "conformance/native/pass/indexing-primitives.0", "conformance/native/pass/checked-bounds-get.0", "conformance/native/pass/check-maybe-fallibility.0", "conformance/native/pass/fallibility-error-sets.0", "conformance/native/pass/checked-fallible-wrapper.0", "conformance/native/pass/checked-fallible-static-method.0", "conformance/native/pass/checked-fallible-interface-method.0", "conformance/native/pass/fallibility-check-value.0", "conformance/native/pass/rescue-check.0", "conformance/native/pass/std-fs-fallible.0", "conformance/native/pass/std-fs-fallible-resources.0", "conformance/native/pass/std-cli-helpers.0", "conformance/native/pass/std-mem-copy-fill.0", "conformance/native/pass/const-layout.0", "conformance/native/pass/c-abi-export.0", "conformance/native/pass/range-slices.0", "conformance/native/pass/byte-view-call-single-eval.0", "conformance/native/pass/generic-spans.0", "conformance/native/pass/open-ended-slices.0", "conformance/native/pass/string-slices.0", "conformance/native/pass/string-param-span-slice.0", "conformance/native/pass/coff-dynamic-byte-slice.0", "conformance/native/pass/macho-large-byte-slice-blocked.0", "conformance/native/pass/macho-nested-call-scratch-blocked.0", "conformance/native/pass/macho-open-byte-slice.0", "conformance/native/pass/string-byte-ergonomics.0", "conformance/native/pass/indexed-mutation.0", "conformance/native/pass/dynamic-indexed-store-scratch.0", "conformance/native/pass/nested-lvalues.0", "conformance/native/pass/mutable-spans.0", "conformance/native/pass/mutref-indexed-lvalues.0", "conformance/native/pass/generic-mem.0", "conformance/native/pass/generic-function-basic.0", "conformance/native/pass/generic-nested-calls.0", "conformance/native/pass/generic-specialization-reuse.0", "conformance/native/pass/generic-multi-specialization.0", "conformance/native/pass/generic-inferred-specialized-call.0", "conformance/native/pass/generic-nested-local-specialization.0", "conformance/native/pass/generic-static-array-specialization.0", "conformance/native/pass/generic-static-forwarded-array-specialization.0", "conformance/native/pass/generic-shape-basic.0", "conformance/native/pass/generic-shape-multi.0", "conformance/native/pass/generic-shape-methods.0", "conformance/native/pass/generic-shape-nested-defaults-alias.0", "conformance/native/pass/generic-constructor-expected.0", "conformance/native/pass/generic-expected-return.0", "conformance/native/pass/generic-literals-arrays.0", "conformance/native/pass/receiver-method-calls.0", "conformance/native/pass/constructors-defaults.0", "conformance/native/pass/static-value-params.0", "conformance/native/pass/static-value-types-const-expr.0", "conformance/native/pass/compile-time-v1.0", "conformance/native/pass/static-interface-basic.0", "conformance/native/pass/static-interface-mutref.0", "conformance/native/pass/static-interface-static-param.0", "conformance/native/pass/top-level-const.0", "conformance/native/pass/const-arithmetic.0", "conformance/native/pass/type-alias-basic.0", "conformance/native/pass/static-method-namespace.0", "conformance/native/pass/c-import-type-shadowing.0", "conformance/native/pass/c-import-alias-later-local.0", "conformance/native/pass/memory-types.0", "conformance/native/pass/owned-transfer.0", "conformance/native/pass/owned-field-move-return-branch.0", "conformance/native/pass/owned-field-reassignment-after-move.0", "conformance/native/pass/owned-array-static-index-reassignment.0", "conformance/native/pass/owned-mutspan-alias-reassignment-after-move.0", "conformance/native/pass/maybe-owned-null-repeat.0", "conformance/native/pass/owned-drop-cleanup.0", "conformance/native/pass/owned-drop-move-suppressed.0", "conformance/native/pass/borrow-primitives.0", "conformance/native/pass/borrow-field-independent-assignment.0", "conformance/native/pass/borrow-aggregate-reassignment-same-origin.0", "conformance/native/pass/receiver-return-field-origin-clears-other-field.0", "conformance/native/pass/borrow-return-param-field-subpath.0", "conformance/native/pass/borrow-return-explicit-ref-field-origin.0", "conformance/native/pass/borrow-unreachable-return-origin.0", "conformance/native/pass/borrow-unreachable-loop-return-origin.0", "conformance/native/pass/borrow-unreachable-if-return-origin.0", "conformance/native/pass/borrow-unreachable-match-return-origin.0", "conformance/native/pass/borrow-unreachable-raise-return-origin.0", "conformance/native/pass/borrow-return-ref-alias-field.0", "conformance/native/pass/assignment-rhs-side-effect-clears-old-origin.0", "conformance/native/pass/shadowed-mutref-side-effect-clears-old-origin.0", "conformance/native/pass/mutref-alias-assignment-clears-old-origin.0", "conformance/native/pass/mutref-alias-assignment-same-origin.0", "conformance/native/pass/function-mutref-reference-store.0", "conformance/native/pass/generic-mutref-reference-store.0", "conformance/native/pass/receiver-method-reference-store.0", "conformance/native/pass/static-interface-mutref-reference-store.0", "conformance/native/pass/static-interface-return-reference-origin.0", "conformance/native/pass/borrow-return-param-ref.0", "conformance/native/pass/borrow-assignment-same-origin.0", "conformance/native/pass/borrow-shadowed-root-reassignment.0", "conformance/native/pass/borrow-branch-reassignment.0", "conformance/native/pass/branch-overwrite-away-reference-origin.0", "conformance/native/pass/shape-field-reference-reassignment-clears-origin.0", "conformance/native/pass/index-reference-assignment-clears-origin.0", "conformance/native/pass/allocator-primitives.0", "conformance/native/pass/std-mem-arena.0", "conformance/native/pass/std-mem-collections.0", "conformance/native/pass/std-collections-algorithms.0", "conformance/native/pass/std-collections-u8.0", "conformance/native/pass/std-collections-mutspan-memory.0", "conformance/native/pass/std-collections-usize-memory.0", "conformance/native/pass/std-collections-query-memory.0", "conformance/native/pass/std-search-sort-widths.0", "conformance/native/pass/owned-byte-buffer.0", "conformance/check/pass/generic-function-basic.0", "conformance/check/pass/generic-array-inference.0", "conformance/check/pass/generic-static-explicit-shadowing.0", "conformance/check/pass/generic-static-forwarding.0", "conformance/check/pass/generic-static-method-forwarding.0", "conformance/check/pass/generic-static-return-substitution.0", "conformance/check/pass/generic-static-wrapper-type-collision.0", "conformance/check/pass/static-interface-return-substitution.0", "conformance/check/pass/generic-untyped-static-const-inference.0", "conformance/check/pass/generic-const-shadowing.0", "conformance/check/pass/generic-const-type-name-collision.0", "conformance/check/pass/generic-mixed-const-type-name-collision.0", "conformance/check/pass/generic-method-outer-param-inference.0", "conformance/native/pass/generic-nested-calls.0", "conformance/native/pass/generic-specialization-reuse.0", "conformance/native/pass/generic-multi-specialization.0", "conformance/native/pass/generic-inferred-specialized-call.0", "conformance/native/pass/generic-nested-local-specialization.0", "conformance/native/pass/generic-static-array-specialization.0", "conformance/native/pass/generic-static-forwarded-array-specialization.0", "conformance/check/pass/generic-shape-basic.0", "conformance/check/pass/generic-shape-multi.0", "conformance/check/pass/generic-shape-methods.0", "conformance/native/pass/generic-constructor-expected.0", "conformance/native/pass/generic-literals-arrays.0", "conformance/check/pass/receiver-method-calls.0", "conformance/check/pass/shape-field-defaults.0", "conformance/check/pass/static-value-params.0", "conformance/check/pass/static-interface-basic.0", "conformance/check/pass/call-resolution-edge-cases.0", "conformance/native/pass/static-interface-mutref.0", "conformance/native/pass/static-interface-static-param.0", "conformance/check/pass/top-level-const.0", "conformance/check/pass/const-arithmetic.0", "conformance/check/pass/type-alias-basic.0", "conformance/check/pass/static-method-namespace.0", "conformance/check/pass/fmt-core-usability.0", "conformance/check/pass/c-header-import.0", "conformance/check/pass/c-import-local-shadowing.0", "conformance/check/pass/match-fallback.0", "conformance/check/pass/memory-types.0", "conformance/check/pass/std-mem-field-items.0", "conformance/check/pass/std-mem-field-slice.0", "conformance/check/pass/fixed-array-length-match.0", "conformance/check/pass/imports", "examples/memory-package", "examples/const-arithmetic.0", "examples/generic-pair.0", "examples/fixed-vec.0", "examples/static-value-params.0", "examples/compile-time-v1.0", "examples/type-alias.0", "examples/static-method.0", "examples/static-interface.0", "examples/ownership-cleanup.0", ]; await mapLimit(passCheckFixtures, checkJobs, (fixture, _index, workerIndex) => checkFixtureParallel(fixture, workerIndex)); const stdSortMergeOverlap = await writeImportFailureFixture(`${outDir}/std-sort-merge-overlap.0`, `pub fn main() -> Void { var values: [5]i32 = [1, 3, 5, 2, 4] let written: usize = std.sort.mergeSortedI32(values, std.mem.prefix(values, 3_usize), std.mem.dropPrefix(values, 3_usize)) } `); assert.equal(stdSortMergeOverlap.diagnostics[0].code, "STD003"); assert.match(stdSortMergeOverlap.diagnostics[0].message, /std\.sort\.mergeSorted source must not overlap destination storage/); const stdMemStartsWithMismatch = await writeImportFailureFixture(`${outDir}/std-mem-startswith-mismatch.0`, `pub fn main() -> Void { let left_values: [2]i32 = [1, 2] let right_values: [2]u32 = [1_u32, 2_u32] let left: Span = left_values let right: Span = right_values let ok: Bool = std.mem.startsWith(left, right) } `); assert.equal(stdMemStartsWithMismatch.diagnostics[0].code, "STD003"); assert.match(stdMemStartsWithMismatch.diagnostics[0].message, /std\.mem\.startsWith span element types must match/); const stdMemStartsWithUnsupported = await writeImportFailureFixture(`${outDir}/std-mem-startswith-unsupported.0`, `type Point { x: i32, } pub fn main() -> Void { let points: [1]Point = [Point { x: 1 }] let span: Span = points let ok: Bool = std.mem.startsWith(span, span) } `); assert.equal(stdMemStartsWithUnsupported.diagnostics[0].code, "STD003"); assert.match(stdMemStartsWithUnsupported.diagnostics[0].message, /std\.mem\.startsWith item element type is not supported/); // Fixtures using the gated typed graph MIR constructs fail check with the // same BLD004 diagnostics zero build reports for their graph stores. const gateBlockedCheckFixtures = [ "conformance/check/pass/package", "conformance/native/pass/variants-defer-stdlib.0", "conformance/native/pass/defer-return-raise-nested.0", "conformance/native/pass/payload-match.0", "conformance/native/pass/match-payload-binding.0", "conformance/native/pass/match-choice-fallback.0", "conformance/native/pass/maybe-error-flow.0", "conformance/native/pass/match-fallback.0", "conformance/check/pass/call-resolution-inspection.0", "conformance/check/pass/checker-type-forms.0", ]; await mapLimit(gateBlockedCheckFixtures, checkJobs, (fixture, _index, workerIndex) => checkFailureFixtureParallel(fixture, /BLD004/, workerIndex)); const checkJsonSuccess = await execFileAsync(zero, ["check", "--json", "conformance/native/pass/explicit-casts.0"]); const checkJsonSuccessBody = JSON.parse(checkJsonSuccess.stdout); assert.equal(checkJsonSuccessBody.ok, true); assert.equal(checkJsonSuccessBody.diagnostics.length, 0); assert.equal(checkJsonSuccessBody.artifact, "conformance/native/pass/explicit-casts.graph"); assert.equal(checkJsonSuccessBody.canonicalSource, false); assert.equal(checkJsonSuccessBody.moduleIdentity, "module:explicit-casts"); assert.match(checkJsonSuccessBody.graphHash, /^graph:[0-9a-f]{16}$/); assert.equal(checkJsonSuccessBody.check.phase, "typecheck"); assert.equal(checkJsonSuccessBody.check.lowering, "graph-native-check"); assert.equal(checkJsonSuccessBody.graphCompiler.input, "program-graph-artifact"); assert.equal(checkJsonSuccessBody.graphCompiler.graphNativeCheckerUsed, true); assert.equal(checkJsonSuccessBody.graphCompiler.graphHirToMirUsed, true); const stdDiagGraphCheck = await execFileAsync(zero, ["check", "--json", "conformance/native/pass/std-diag.graph"]); const stdDiagGraphCheckBody = JSON.parse(stdDiagGraphCheck.stdout); assert.equal(stdDiagGraphCheckBody.ok, true); assert.equal(stdDiagGraphCheckBody.targetReadiness.ok, true); assert.equal(stdDiagGraphCheckBody.targetReadiness.buildable, true); assert.equal(stdDiagGraphCheckBody.targetReadiness.diagnostics.length, 0); const agentSurfaceClassification = JSON.parse(await readFile("conformance/agent-surface/classification.json", "utf8")); assert.equal(agentSurfaceClassification.schema, 1); assert.deepEqual(agentSurfaceClassification.fixtures.map((item) => item.id), [ "interface-method-generic-binding", "direct-generic-recursion", "direct-generic-specialization-name-collision", "stdlib-signature-parity", "owned-drop-direct-backend-unsupported", ]); const agentSurfaceInterfaceMethodGeneric = await execFileAsync(zero, ["check", "--json", "conformance/agent-surface/fixtures/interface-method-generic-binding.0"]); const agentSurfaceInterfaceMethodGenericBody = JSON.parse(agentSurfaceInterfaceMethodGeneric.stdout); assert.equal(agentSurfaceInterfaceMethodGenericBody.ok, true); assert.equal(agentSurfaceInterfaceMethodGenericBody.diagnostics.length, 0); const agentSurfaceDirectGenericCheck = await execFileAsync(zero, ["check", "--json", "conformance/agent-surface/fixtures/direct-generic-recursion.0"]); const agentSurfaceDirectGenericCheckBody = JSON.parse(agentSurfaceDirectGenericCheck.stdout); assert.equal(agentSurfaceDirectGenericCheckBody.ok, true); assert.equal(agentSurfaceDirectGenericCheckBody.diagnostics.length, 0); const agentSurfaceDirectGenericReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "linux-musl-x64", "conformance/agent-surface/fixtures/direct-generic-recursion.0", ]); const agentSurfaceDirectGenericReadinessBody = JSON.parse(agentSurfaceDirectGenericReadiness.stdout); assert.equal(agentSurfaceDirectGenericReadinessBody.ok, true); assert.equal(agentSurfaceDirectGenericReadinessBody.targetReadiness.ok, true); assert.equal(agentSurfaceDirectGenericReadinessBody.targetReadiness.buildable, true); assert.equal(agentSurfaceDirectGenericReadinessBody.targetReadiness.diagnostics.length, 0); const agentSurfaceDirectGenericCollisionReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "linux-musl-x64", "conformance/agent-surface/fixtures/direct-generic-specialization-name-collision.0", ]); const agentSurfaceDirectGenericCollisionReadinessBody = JSON.parse(agentSurfaceDirectGenericCollisionReadiness.stdout); assert.equal(agentSurfaceDirectGenericCollisionReadinessBody.ok, true); assert.equal(agentSurfaceDirectGenericCollisionReadinessBody.targetReadiness.ok, false); assert.equal(agentSurfaceDirectGenericCollisionReadinessBody.targetReadiness.buildable, false); assert.equal(agentSurfaceDirectGenericCollisionReadinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.match(agentSurfaceDirectGenericCollisionReadinessBody.targetReadiness.diagnostics[0].message, /specialization name collides/); const compilerMetrics = await execFileAsync("node", ["--experimental-strip-types", "--disable-warning=ExperimentalWarning", "scripts/compiler-metrics.mts"]); const compilerMetricsBody = JSON.parse(compilerMetrics.stdout); assert.equal(compilerMetricsBody.schema, 1); assert(compilerMetricsBody.files["native/zero-c/src/checker.c"].lines > 0); assert.equal(compilerMetricsBody.files["native/zero-c/src/fs.c"].shellCalls, 0); assert.equal(compilerMetricsBody.files["native/zero-c/src/main.c"].shellCalls, 0); for (const [path, metrics] of Object.entries(compilerMetricsBody.files)) { assert.equal(metrics.shellCalls, 0, `${path} should not introduce shell execution calls`); } const relativeToolDir = `${outDir}/relative-tools`; await mkdir(relativeToolDir, { recursive: true }); await writeFile(`${relativeToolDir}/cc`, "#!/bin/sh\nprintf 'fake relative cc\\n'\n"); await chmod(`${relativeToolDir}/cc`, 0o755); const relativePathDoctor = await execFileAsync(zero, ["doctor", "--json"], { env: { ...process.env, PATH: relativeToolDir } }).catch((error) => error); assert.notEqual(relativePathDoctor.code, 0); const relativePathDoctorBody = JSON.parse(relativePathDoctor.stdout); const relativePathNativeCompiler = relativePathDoctorBody.checks.find((check) => check.name === "native-c-compiler"); assert.equal(relativePathNativeCompiler.status, "error"); assert.match(relativePathNativeCompiler.message, /no native C compiler found/); assert(Array.isArray(compilerMetricsBody.largeFunctions)); assert(compilerMetricsBody.stdlib.mainHelperCount > 0); assert.equal(compilerMetricsBody.stdlib.mainHelperCount, compilerMetricsBody.stdlib.checkerReturnCount); assert.equal(compilerMetricsBody.stdlib.mainHelperCount, compilerMetricsBody.stdlib.checkerArgCountCount); assert.deepEqual(compilerMetricsBody.stdlib.duplicateCheckerReturnTypes, []); assert.deepEqual(compilerMetricsBody.stdlib.duplicateCheckerArgCounts, []); assert.deepEqual(compilerMetricsBody.stdlib.checkerReturnsMissingFromMainHelpers, []); assert.deepEqual(compilerMetricsBody.stdlib.mainHelpersMissingFromCheckerReturns, []); assert.deepEqual(compilerMetricsBody.stdlib.checkerArgCountsMissingFromMainHelpers, []); assert.deepEqual(compilerMetricsBody.stdlib.mainHelpersMissingFromCheckerArgCounts, []); assert.deepEqual(compilerMetricsBody.stdlib.argCountMismatches, []); assert.equal(compilerMetricsBody.stdlib.sharedSignatureLookup.checkerReturnTypes, true); assert.equal(compilerMetricsBody.stdlib.sharedSignatureLookup.checkerArgCounts, true); assert.equal(compilerMetricsBody.backendFormats.elf.sharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.elf.x86ObjectUsesSharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.elf.x86ExecutableUsesSharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.elf.aarch64ObjectUsesSharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.elf.aarch64ExecutableUsesSharedWriter, true); assert.deepEqual(compilerMetricsBody.backendFormats.elf.archFilesWithLocalSectionWriters, []); assert.equal(compilerMetricsBody.backendFormats.elf.patchStateModule, true); assert.equal(compilerMetricsBody.backendFormats.elf.x86UsesPatchStateModule, true); assert.deepEqual(compilerMetricsBody.backendFormats.elf.archFilesWithLocalPatchState, []); assert.equal(compilerMetricsBody.backendFormats.coff.sharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.coff.objectUsesSharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.coff.executableUsesSharedWriter, true); assert.deepEqual(compilerMetricsBody.backendFormats.coff.archFilesWithLocalContainerWriters, []); assert.equal(compilerMetricsBody.backendFormats.coff.patchStateModule, true); assert.equal(compilerMetricsBody.backendFormats.coff.x64UsesPatchStateModule, true); assert.deepEqual(compilerMetricsBody.backendFormats.coff.archFilesWithLocalPatchState, []); assert.equal(compilerMetricsBody.backendFormats.macho.sharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.macho.objectUsesSharedWriter, true); assert.equal(compilerMetricsBody.backendFormats.macho.executableUsesSharedWriter, true); assert.deepEqual(compilerMetricsBody.backendFormats.macho.archFilesWithLocalContainerWriters, []); assert.equal(compilerMetricsBody.backendFormats.macho.patchStateModule, true); assert.equal(compilerMetricsBody.backendFormats.macho.archFileUsesPatchStateModule, true); assert.deepEqual(compilerMetricsBody.backendFormats.macho.archFilesWithLocalPatchState, []); assert.equal(compilerMetricsBody.backendFormats.x64.sharedEncodingPrimitives, true); assert.equal(compilerMetricsBody.backendFormats.x64.elfUsesSharedEncodingPrimitives, true); assert.equal(compilerMetricsBody.backendFormats.x64.coffUsesSharedEncodingPrimitives, true); assert.deepEqual(compilerMetricsBody.backendFormats.x64.formatFilesWithLocalEncodingPrimitives, []); assert.equal(compilerMetricsBody.backendFormats.aarch64.sharedEncodingPrimitives, true); assert.equal(compilerMetricsBody.backendFormats.aarch64.elfUsesSharedEncodingPrimitives, true); assert.equal(compilerMetricsBody.backendFormats.aarch64.machoUsesSharedEncodingPrimitives, true); assert.deepEqual(compilerMetricsBody.backendFormats.aarch64.formatFilesWithLocalEncodingPrimitives, []); assert.equal(compilerMetricsBody.budget.ok, true); assert.deepEqual(compilerMetricsBody.budget.violations, []); assert.equal(typeof compilerMetricsBody.budget.reportThreshold, "number"); for (const item of compilerMetricsBody.largeFunctions) { assert.equal(typeof item.path, "string"); assert.equal(typeof item.signature, "string"); assert.equal(typeof item.line, "number"); assert.equal(typeof item.lines, "number"); assert(item.lines >= compilerMetricsBody.budget.reportThreshold); } const unsafeCompilerOverrideBuild = await execFileAsync(zero, [ "build", "--json", "--out", `${outDir}/unsafe-cc-override`, "examples/json-api-client.graph", ], { env: { ...process.env, ZERO_CC: "cc;touch" } }).catch((error) => error); assert.notEqual(unsafeCompilerOverrideBuild.code, 0); assert.match(unsafeCompilerOverrideBuild.stderr, /compiler override contains unsafe shell characters/); const unsafeCompilerOverrideBody = JSON.parse(unsafeCompilerOverrideBuild.stdout); assert.equal(unsafeCompilerOverrideBody.ok, false); assert.equal(unsafeCompilerOverrideBody.diagnostics[0].code, "BLD003"); assert.equal(unsafeCompilerOverrideBody.diagnostics[0].actual, "compiler override contains unsafe shell characters"); assert.match(unsafeCompilerOverrideBody.diagnostics[0].help, /without flags, whitespace, or shell syntax/); const agentSurfaceBorrowExplain = await execFileAsync(zero, ["explain", "--json", "BOR001"]); const agentSurfaceBorrowExplainBody = JSON.parse(agentSurfaceBorrowExplain.stdout); assert.equal(agentSurfaceBorrowExplainBody.code, "BOR001"); assert.equal(agentSurfaceBorrowExplainBody.repair.id, "end-conflicting-borrow"); assert.match(agentSurfaceBorrowExplainBody.summary, /lexical scope/); const agentSurfaceMalformedLocalUseFixture = `${outDir}/malformed-local-use.0`; await writeFile(agentSurfaceMalformedLocalUseFixture, 'use local.\n\npub fn main(world: World) -> Void raises {\n check world.out.write("malformed local use parser fixture\\n")\n}\n'); const agentSurfaceMalformedLocalUse = await execFileAsync(zero, ["parse", "--json", agentSurfaceMalformedLocalUseFixture]).catch((error) => error); assert.notEqual(agentSurfaceMalformedLocalUse.code, 0); const agentSurfaceMalformedLocalUseBody = JSON.parse(agentSurfaceMalformedLocalUse.stdout); assert.equal(agentSurfaceMalformedLocalUseBody.diagnostics[0].code, "PAR100"); assert.match(agentSurfaceMalformedLocalUseBody.diagnostics[0].message, /expected import module segment/); assert.equal(agentSurfaceMalformedLocalUseBody.diagnostics[0].line, 1); assert.equal(agentSurfaceMalformedLocalUseBody.diagnostics[0].column, 11); const agentSurfaceSplitUseFixture = `${outDir}/split-use-path.0`; await writeFile(agentSurfaceSplitUseFixture, 'use std.\ncodec\n\npub fn main(world: World) -> Void raises {\n check world.out.write("split use parser fixture\\n")\n}\n'); const agentSurfaceSplitUse = await execFileAsync(zero, ["parse", "--json", agentSurfaceSplitUseFixture]).catch((error) => error); assert.notEqual(agentSurfaceSplitUse.code, 0); const agentSurfaceSplitUseBody = JSON.parse(agentSurfaceSplitUse.stdout); assert.equal(agentSurfaceSplitUseBody.diagnostics[0].code, "PAR100"); assert.match(agentSurfaceSplitUseBody.diagnostics[0].message, /expected import module segment/); assert.equal(agentSurfaceSplitUseBody.diagnostics[0].line, 1); assert.equal(agentSurfaceSplitUseBody.diagnostics[0].column, 9); const agentSurfaceKeywordUseFixture = `${outDir}/keyword-use.0`; await writeFile(agentSurfaceKeywordUseFixture, 'use pub\n\npub fn main(world: World) -> Void raises {\n check world.out.write("keyword use parser fixture\\n")\n}\n'); const agentSurfaceKeywordUse = await execFileAsync(zero, ["parse", "--json", agentSurfaceKeywordUseFixture]).catch((error) => error); assert.notEqual(agentSurfaceKeywordUse.code, 0); const agentSurfaceKeywordUseBody = JSON.parse(agentSurfaceKeywordUse.stdout); assert.equal(agentSurfaceKeywordUseBody.diagnostics[0].code, "PAR100"); assert.match(agentSurfaceKeywordUseBody.diagnostics[0].message, /reserved word cannot be used as an identifier/); assert.equal(agentSurfaceKeywordUseBody.diagnostics[0].line, 1); assert.equal(agentSurfaceKeywordUseBody.diagnostics[0].column, 5); const agentSurfaceOwnedDropCheck = await execFileAsync(zero, ["check", "--json", "conformance/agent-surface/fixtures/owned-drop-direct-backend-unsupported.0"]); const agentSurfaceOwnedDropCheckBody = JSON.parse(agentSurfaceOwnedDropCheck.stdout); assert.equal(agentSurfaceOwnedDropCheckBody.ok, true); const agentSurfaceOwnedDropReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "linux-musl-x64", "conformance/agent-surface/fixtures/owned-drop-direct-backend-unsupported.0", ]); const agentSurfaceOwnedDropReadinessBody = JSON.parse(agentSurfaceOwnedDropReadiness.stdout); assert.equal(agentSurfaceOwnedDropReadinessBody.ok, true); assert.equal(agentSurfaceOwnedDropReadinessBody.diagnostics.length, 0); assert.equal(agentSurfaceOwnedDropReadinessBody.targetReadiness.ok, false); assert.equal(agentSurfaceOwnedDropReadinessBody.targetReadiness.buildable, false); assert.equal(agentSurfaceOwnedDropReadinessBody.targetReadiness.languageOk, true); assert.equal(agentSurfaceOwnedDropReadinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.deepEqual(agentSurfaceOwnedDropReadinessBody.targetReadiness.diagnostics[0].backendBlocker, { target: "linux-musl-x64", objectFormat: "elf", backend: "zero-elf64", stage: "lower", unsupportedFeature: "owned", }); const directCallExeReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "exe", "--target", "linux-musl-x64", "examples/direct-call-add.0", ]); const directCallExeReadinessBody = JSON.parse(directCallExeReadiness.stdout); assert.equal(directCallExeReadinessBody.ok, true); assert.equal(directCallExeReadinessBody.diagnostics.length, 0); assert.equal(directCallExeReadinessBody.targetReadiness.ok, false); assert.equal(directCallExeReadinessBody.targetReadiness.buildable, false); assert.equal(directCallExeReadinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(directCallExeReadinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "buildability"); assert.match(directCallExeReadinessBody.targetReadiness.diagnostics[0].message, /main must not take parameters/); const directCallExeBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "exe", "--target", "linux-musl-x64", "examples/direct-call-add.0", "--out", `${outDir}/direct-call-add-blocked`, ]).catch((error) => error); assert.notEqual(directCallExeBuild.code, 0); const directCallExeBuildBody = JSON.parse(directCallExeBuild.stdout); const directCallReadinessDiag = directCallExeReadinessBody.targetReadiness.diagnostics[0]; const directCallBuildDiag = directCallExeBuildBody.diagnostics[0]; for (const key of ["code", "path", "line", "column", "length", "expected", "actual", "help"]) { assert.equal(directCallBuildDiag[key], directCallReadinessDiag[key]); } assert.equal(directCallBuildDiag.backendBlocker.stage, "buildability"); const directCallExeGraph = await execFileAsync(zero, [ "inspect", "--json", "--emit", "exe", "--target", "linux-musl-x64", "examples/direct-call-add.0", ]); const directCallExeGraphBody = JSON.parse(directCallExeGraph.stdout); assert.equal(directCallExeGraphBody.targetReadiness.ok, false); assert.equal(directCallExeGraphBody.targetReadiness.diagnostics[0].code, "BLD004"); const directCallGraphDiag = directCallExeGraphBody.targetReadiness.diagnostics[0]; assert.equal(directCallGraphDiag.path, "direct-call-add.0"); assert.equal(directCallGraphDiag.expected, "direct ELF64 object subset"); assert.equal(directCallGraphDiag.actual, "unsupported construct"); assert.equal(directCallGraphDiag.backendBlocker.backend, "zero-elf64-exe"); assert.equal(directCallGraphDiag.backendBlocker.stage, "lower"); const llvmLoopIrPath = `${outDir}/llvm-direct-while-sum.ll`; await execFileAsync(zero, [ "build", "--emit", "llvm-ir", "--backend", "llvm", "examples/direct-while-sum.0", "--out", llvmLoopIrPath, ]); const llvmLoopIr = await readFile(llvmLoopIrPath, "utf8"); assert.match(llvmLoopIr, /^; zero llvm-ir v1\n/); assert.match(llvmLoopIr, /target triple = "/); assert.match(llvmLoopIr, /define i32 @main\(\) \{/); assert.match(llvmLoopIr, /br label %L0\nL0:\n/); assert.match(llvmLoopIr, /icmp slt i32 %v[0-9]+, 5/); assert.match(llvmLoopIr, /add i32 %v[0-9]+, %v[0-9]+/); assert.match(llvmLoopIr, /ret i32 %v[0-9]+/); const llvmArrayIr = await buildLlvmIrFixture("examples/direct-array-sum.0", "llvm-direct-array-sum"); assert.match(llvmArrayIr, /alloca \[4 x i32\]/); assert.match(llvmArrayIr, /getelementptr inbounds \[4 x i32\], ptr %slot[0-9]+, i64 0, i64 0/); assert.match(llvmArrayIr, /getelementptr inbounds \[4 x i32\], ptr %slot[0-9]+, i64 0, i64 %v[0-9]+/); assert.match(llvmArrayIr, /store i32 4, ptr %v[0-9]+, align 4/); assert.match(llvmArrayIr, /load i32, ptr %v[0-9]+, align 4/); assert.match(llvmArrayIr, /call void @llvm\.trap\(\)/); await assertLlvmHostExitCode("examples/direct-array-sum.0", "llvm-direct-array-sum", 10); const llvmStringLenIr = await buildLlvmIrFixture("examples/direct-string-len.0", "llvm-direct-string-len"); assert.match(llvmStringLenIr, /@\.zero\.data\.0 = private unnamed_addr constant \[6 x i8\] c"token\\00", align 1/); assert.match(llvmStringLenIr, /insertvalue \{ ptr, i64 \} poison, ptr %v[0-9]+, 0/); assert.match(llvmStringLenIr, /insertvalue \{ ptr, i64 \} %v[0-9]+, i64 5, 1/); assert.match(llvmStringLenIr, /ret i64 5/); await assertLlvmHostExitCode("examples/direct-string-len.0", "llvm-direct-string-len", 5); const llvmByteCopyFillIr = await buildLlvmIrFixture("examples/direct-byte-copy-fill.0", "llvm-direct-byte-copy-fill"); assert.match(llvmByteCopyFillIr, /declare void @llvm\.memcpy\.p0\.p0\.i64\(ptr, ptr, i64, i1\)/); assert.match(llvmByteCopyFillIr, /declare void @llvm\.memset\.p0\.i64\(ptr, i8, i64, i1\)/); assert.match(llvmByteCopyFillIr, /alloca \[5 x i8\]/); assert.match(llvmByteCopyFillIr, /call void @llvm\.memset\.p0\.i64\(ptr %v[0-9]+, i8 33, i64 (?:5|%v[0-9]+), i1 false\)/); assert.match(llvmByteCopyFillIr, /select i1 %v[0-9]+, i64 %v[0-9]+, i64 %v[0-9]+/); assert.match(llvmByteCopyFillIr, /call void @llvm\.memcpy\.p0\.p0\.i64\(ptr %v[0-9]+, ptr %v[0-9]+, i64 %v[0-9]+, i1 false\)/); await assertLlvmHostExitCode("examples/direct-byte-copy-fill.0", "llvm-direct-byte-copy-fill", 111); const llvmStringEqlIr = await buildLlvmIrFixture("examples/direct-string-eql.0", "llvm-direct-string-eql"); assertLlvmPhiPredecessors(llvmStringEqlIr); assert.match(llvmStringEqlIr, /phi i64 \[0, %L[0-9]+\], \[%v[0-9]+, %L[0-9]+\]/); assert.match(llvmStringEqlIr, /icmp eq i8 %v[0-9]+, %v[0-9]+/); assert.match(llvmStringEqlIr, /phi i1 \[1, %L[0-9]+\], \[0, %L[0-9]+\]/); await assertLlvmHostExitCode("examples/direct-string-eql.0", "llvm-direct-string-eql", 1); const llvmByteViewLocalsIr = await buildLlvmIrFixture("examples/direct-byte-view-locals.0", "llvm-direct-byte-view-locals"); assertLlvmPhiPredecessors(llvmByteViewLocalsIr); assert.match(llvmByteViewLocalsIr, /alloca \{ ptr, i64 \}/); assert.match(llvmByteViewLocalsIr, /store \{ ptr, i64 \} %v[0-9]+, ptr %slot[0-9]+, align 8/); assert.match(llvmByteViewLocalsIr, /load \{ ptr, i64 \}, ptr %slot[0-9]+, align 8/); assert.match(llvmByteViewLocalsIr, /extractvalue \{ ptr, i64 \} %v[0-9]+, 0/); assert.match(llvmByteViewLocalsIr, /extractvalue \{ ptr, i64 \} %v[0-9]+, 1/); await assertLlvmHostExitCode("examples/direct-byte-view-locals.0", "llvm-direct-byte-view-locals", 107); const llvmSpanReadIr = await buildLlvmIrFixture("examples/direct-span-read.0", "llvm-direct-span-read"); assert.match(llvmSpanReadIr, /icmp ule i64 %v[0-9]+, %v[0-9]+/); assert.match(llvmSpanReadIr, /icmp ult i64 %v[0-9]+, %v[0-9]+/); assert.match(llvmSpanReadIr, /getelementptr inbounds i8, ptr %v[0-9]+, i64 %v[0-9]+/); assert.match(llvmSpanReadIr, /load i8, ptr %v[0-9]+, align 1/); await assertLlvmHostExitCode("examples/direct-span-read.0", "llvm-direct-span-read", 107); const llvmShortCircuitSourcePath = `${outDir}/llvm-short-circuit.0`; const llvmShortCircuitIrPath = `${outDir}/llvm-short-circuit.ll`; await writeGraphFixture(llvmShortCircuitSourcePath, `fn rhsAnd() -> Bool { return true } fn rhsOr() -> Bool { return false } export c fn main() -> i32 { if false && rhsAnd() { return 1 } if true || rhsOr() { return 2 } if true && (false && rhsAnd()) { return 3 } if false || (true || rhsOr()) { return 4 } return 0 } `); await execFileAsync(zero, [ "build", "--emit", "llvm-ir", "--backend", "llvm", llvmShortCircuitSourcePath, "--out", llvmShortCircuitIrPath, ]); const llvmShortCircuitIr = await readFile(llvmShortCircuitIrPath, "utf8"); assertLlvmPhiPredecessors(llvmShortCircuitIr); assert.match(llvmShortCircuitIr, /br i1 0, label %L[0-9]+, label %L[0-9]+\nL[0-9]+:\n %v[0-9]+ = call i1 @\.zero\.fn\.[0-9]+\.rhsAnd\(\)/); assert.match(llvmShortCircuitIr, /%v[0-9]+ = phi i1 \[%v[0-9]+, %L[0-9]+\], \[0, %L[0-9]+\]/); assert.match(llvmShortCircuitIr, /br i1 1, label %L[0-9]+, label %L[0-9]+\nL[0-9]+:\n %v[0-9]+ = call i1 @\.zero\.fn\.[0-9]+\.rhsOr\(\)/); assert.match(llvmShortCircuitIr, /%v[0-9]+ = phi i1 \[%v[0-9]+, %L[0-9]+\], \[1, %L[0-9]+\]/); const llvmAddIrPath = `${outDir}/llvm-add.ll`; const llvmAddBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "llvm-ir", "--backend", "llvm", "examples/add.0", "--out", llvmAddIrPath, ]); const llvmAddBuildBody = JSON.parse(llvmAddBuild.stdout); assert.equal(llvmAddBuildBody.objectBackend.linking.targetLibraries, "zero-runtime"); assert.equal(llvmAddBuildBody.objectBackend.linking.toolchainSource, "textual-llvm-ir-runtime-link-plan"); assert.deepEqual(llvmAddBuildBody.objectBackend.linkerPlan.staticLibraries, ["zero_runtime.o"]); const llvmAddIr = await readFile(llvmAddIrPath, "utf8"); assert.match(llvmAddIr, /@\.zero\.data\.0 = private unnamed_addr constant \[12 x i8\] c"math works\\0A\\00", align 1/); assert.match(llvmAddIr, /declare i32 @zero_world_write\(i32, ptr, i32\)/); assert.match(llvmAddIr, /declare void @llvm\.trap\(\)/); assert.match(llvmAddIr, /define i32 @\.zero\.fn\.[0-9]+\.answer\(\) \{/); assert.match(llvmAddIr, /call i32 @zero_world_write\(i32 1, ptr %v[0-9]+, i32 (?:11|%v[0-9]+)\)/); assert.match(llvmAddIr, /%v[0-9]+ = call i32 @zero_world_write\(i32 1, ptr %v[0-9]+, i32 (?:11|%v[0-9]+)\)\n %v[0-9]+ = icmp eq i32 %v[0-9]+, 0\n br i1 %v[0-9]+, label %L[0-9]+, label %L[0-9]+\nL[0-9]+:\n call void @llvm\.trap\(\)\n unreachable\nL[0-9]+:/); const llvmSymbolCollisionSourcePath = `${outDir}/llvm-symbol-collision.0`; const llvmSymbolCollisionIrPath = `${outDir}/llvm-symbol-collision.ll`; await writeGraphFixture(llvmSymbolCollisionSourcePath, `fn foo() -> i32 { return 1 } export c fn z_fn_0_foo() -> i32 { return 2 } export c fn main() -> i32 { return foo() + z_fn_0_foo() } `); await execFileAsync(zero, [ "build", "--emit", "llvm-ir", "--backend", "llvm", llvmSymbolCollisionSourcePath, "--out", llvmSymbolCollisionIrPath, ]); const llvmSymbolCollisionIr = await readFile(llvmSymbolCollisionIrPath, "utf8"); assert.match(llvmSymbolCollisionIr, /define i32 @\.zero\.fn\.[0-9]+\.foo\(\) \{/); assert.match(llvmSymbolCollisionIr, /define i32 @z_fn_0_foo\(\) \{/); assert.match(llvmSymbolCollisionIr, /call i32 @\.zero\.fn\.[0-9]+\.foo\(\)/); assert.equal((llvmSymbolCollisionIr.match(/define i32 @z_fn_0_foo\(\) \{/g) || []).length, 1); const llvmRuntimeCollisionSourcePath = `${outDir}/llvm-runtime-symbol-collision.0`; await writeGraphFixture(llvmRuntimeCollisionSourcePath, `export c fn zero_world_write() -> i32 { return 7 } pub fn main(world: World) -> Void raises { check world.out.write("hello\\n") } `); const llvmRuntimeCollisionReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "llvm-ir", "--backend", "llvm", llvmRuntimeCollisionSourcePath, ]); const llvmRuntimeCollisionReadinessBody = JSON.parse(llvmRuntimeCollisionReadiness.stdout); assert.equal(llvmRuntimeCollisionReadinessBody.ok, true); assert.equal(llvmRuntimeCollisionReadinessBody.targetReadiness.ok, false); assert.equal(llvmRuntimeCollisionReadinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(llvmRuntimeCollisionReadinessBody.targetReadiness.diagnostics[0].actual, "zero_world_write"); assert.equal(llvmRuntimeCollisionReadinessBody.targetReadiness.diagnostics[0].backendBlocker.backend, "llvm"); assert.equal(llvmRuntimeCollisionReadinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "lower"); const llvmRuntimeCollisionBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "llvm-ir", "--backend", "llvm", llvmRuntimeCollisionSourcePath, "--out", `${outDir}/llvm-runtime-symbol-collision.ll`, ]).catch((error) => error); assert.notEqual(llvmRuntimeCollisionBuild.code, 0); const llvmRuntimeCollisionBuildBody = JSON.parse(llvmRuntimeCollisionBuild.stdout); assert.equal(llvmRuntimeCollisionBuildBody.diagnostics[0].actual, "zero_world_write"); assert.equal(llvmRuntimeCollisionBuildBody.diagnostics[0].backendBlocker.backend, "llvm"); const llvmLongExportName = `llvm_export_${"a".repeat(200)}`; const llvmLongExportSourcePath = `${outDir}/llvm-long-export.0`; const llvmLongExportIrPath = `${outDir}/llvm-long-export.ll`; await writeGraphFixture(llvmLongExportSourcePath, `export c fn ${llvmLongExportName}() -> i32 { return 7 } export c fn main() -> i32 { return ${llvmLongExportName}() } `); await execFileAsync(zero, [ "build", "--emit", "llvm-ir", "--backend", "llvm", llvmLongExportSourcePath, "--out", llvmLongExportIrPath, ]); const llvmLongExportIr = await readFile(llvmLongExportIrPath, "utf8"); assert(llvmLongExportIr.includes(`define i32 @${llvmLongExportName}() {`)); assert(llvmLongExportIr.includes(`call i32 @${llvmLongExportName}()`)); const directStringMachOExe = await execFileAsync(zero, [ "build", "--json", "--emit", "exe", "--target", "darwin-arm64", "examples/direct-string-literal.0", "--out", `${outDir}/direct-string-literal-darwin`, ]); const directStringMachOExeBody = JSON.parse(directStringMachOExe.stdout); assert.equal(directStringMachOExeBody.compiler, "zero-macho64"); assert.equal(directStringMachOExeBody.generatedCBytes, 0); const directStringCoffExe = await execFileAsync(zero, [ "build", "--json", "--emit", "exe", "--target", "win32-x64.exe", "examples/direct-string-literal.0", "--out", `${outDir}/direct-string-literal-win`, ]); const directStringCoffExeBody = JSON.parse(directStringCoffExe.stdout); assert.equal(directStringCoffExeBody.compiler, "zero-coff-x64"); assert.equal(directStringCoffExeBody.generatedCBytes, 0); const coffDynamicSliceFixture = "conformance/native/pass/coff-dynamic-byte-slice.0"; const coffDynamicSliceReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffDynamicSliceFixture, ]); const coffDynamicSliceReadinessBody = JSON.parse(coffDynamicSliceReadiness.stdout); assert.equal(coffDynamicSliceReadinessBody.ok, true); assert.equal(coffDynamicSliceReadinessBody.diagnostics.length, 0); assert.equal(coffDynamicSliceReadinessBody.targetReadiness.ok, true); assert.equal(coffDynamicSliceReadinessBody.targetReadiness.buildable, true); assert.equal(coffDynamicSliceReadinessBody.targetReadiness.backend, "zero-coff-x64"); const coffDynamicSliceBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffDynamicSliceFixture, "--out", `${outDir}/coff-dynamic-byte-slice.obj`, ]); const coffDynamicSliceBuildBody = JSON.parse(coffDynamicSliceBuild.stdout); assert.equal(coffDynamicSliceBuildBody.compiler, "zero-coff-x64"); assert.equal(coffDynamicSliceBuildBody.generatedCBytes, 0); assert.equal(coffDynamicSliceBuildBody.objectBackend.objectEmission.path, "direct-coff-x64-object"); await assertCoffX64Object(`${outDir}/coff-dynamic-byte-slice.obj`, "main"); const coffU64CopyFixture = "conformance/native/pass/std-mem-u64-copy-items.0"; const coffU64CopyReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffU64CopyFixture, ]); const coffU64CopyReadinessBody = JSON.parse(coffU64CopyReadiness.stdout); assert.equal(coffU64CopyReadinessBody.ok, true); assert.equal(coffU64CopyReadinessBody.targetReadiness.ok, true); assert.equal(coffU64CopyReadinessBody.targetReadiness.buildable, true); assert.equal(coffU64CopyReadinessBody.targetReadiness.backend, "zero-coff-x64"); const coffU64CopyPath = `${outDir}/coff-u64-copy-items.obj`; const coffU64CopyBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffU64CopyFixture, "--out", coffU64CopyPath, ]); const coffU64CopyBuildBody = JSON.parse(coffU64CopyBuild.stdout); assert.equal(coffU64CopyBuildBody.compiler, "zero-coff-x64"); assert.equal(coffU64CopyBuildBody.generatedCBytes, 0); assert.equal(coffU64CopyBuildBody.objectBackend.objectEmission.path, "direct-coff-x64-object"); const coffU64CopyBytes = await assertCoffX64Object(coffU64CopyPath, "main"); assert(hasX64MovMemoryToR64(coffU64CopyBytes)); assert(hasX64MovR64ToMemory(coffU64CopyBytes)); const coffU64ContainsFixture = "conformance/native/pass/std-mem-u64-contains.0"; const coffU64ContainsReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffU64ContainsFixture, ]); const coffU64ContainsReadinessBody = JSON.parse(coffU64ContainsReadiness.stdout); assert.equal(coffU64ContainsReadinessBody.ok, true); assert.equal(coffU64ContainsReadinessBody.targetReadiness.ok, true); assert.equal(coffU64ContainsReadinessBody.targetReadiness.buildable, true); assert.equal(coffU64ContainsReadinessBody.targetReadiness.backend, "zero-coff-x64"); const coffU64ContainsPath = `${outDir}/coff-u64-contains.obj`; const coffU64ContainsBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffU64ContainsFixture, "--out", coffU64ContainsPath, ]); const coffU64ContainsBuildBody = JSON.parse(coffU64ContainsBuild.stdout); assert.equal(coffU64ContainsBuildBody.compiler, "zero-coff-x64"); assert.equal(coffU64ContainsBuildBody.generatedCBytes, 0); assert.equal(coffU64ContainsBuildBody.objectBackend.objectEmission.path, "direct-coff-x64-object"); const coffU64ContainsBytes = await assertCoffX64Object(coffU64ContainsPath, "main"); assert(coffU64ContainsBytes.includes(Buffer.from([0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00]))); assert(hasX64MovMemoryToR64(coffU64ContainsBytes)); assert(hasX64CmpR64(coffU64ContainsBytes)); const coffBoolCopyFixture = "conformance/native/pass/std-mem-bool-copy-items.0"; const coffBoolCopyReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffBoolCopyFixture, ]); const coffBoolCopyReadinessBody = JSON.parse(coffBoolCopyReadiness.stdout); assert.equal(coffBoolCopyReadinessBody.ok, true); assert.equal(coffBoolCopyReadinessBody.targetReadiness.ok, true); assert.equal(coffBoolCopyReadinessBody.targetReadiness.buildable, true); assert.equal(coffBoolCopyReadinessBody.targetReadiness.backend, "zero-coff-x64"); const coffBoolCopyPath = `${outDir}/coff-bool-copy-items.obj`; const coffBoolCopyBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "win32-x64.exe", coffBoolCopyFixture, "--out", coffBoolCopyPath, ]); const coffBoolCopyBuildBody = JSON.parse(coffBoolCopyBuild.stdout); assert.equal(coffBoolCopyBuildBody.compiler, "zero-coff-x64"); assert.equal(coffBoolCopyBuildBody.generatedCBytes, 0); assert.equal(coffBoolCopyBuildBody.objectBackend.objectEmission.path, "direct-coff-x64-object"); await assertCoffX64Object(coffBoolCopyPath, "main"); async function assertMachOObjectBuildabilityBlocked(fixture, outName, expectedMessage) { const readiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "darwin-arm64", fixture, ]); const readinessBody = JSON.parse(readiness.stdout); assert.equal(readinessBody.ok, true); assert.equal(readinessBody.diagnostics.length, 0); assert.equal(readinessBody.targetReadiness.ok, false); assert.equal(readinessBody.targetReadiness.buildable, false); assert.equal(readinessBody.targetReadiness.languageOk, true); assert.equal(readinessBody.targetReadiness.emit, "obj"); assert.equal(readinessBody.targetReadiness.target, "darwin-arm64"); assert.equal(readinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.backend, "zero-macho64"); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "buildability"); assert.match(readinessBody.targetReadiness.diagnostics[0].message, expectedMessage); const build = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", fixture, "--out", `${outDir}/${outName}`, ]).catch((error) => error); assert.notEqual(build.code, 0); const buildBody = JSON.parse(build.stdout); const readinessDiag = readinessBody.targetReadiness.diagnostics[0]; const buildDiag = buildBody.diagnostics[0]; for (const key of ["code", "path", "line", "column", "length", "expected", "actual", "help"]) { assert.equal(buildDiag[key], readinessDiag[key]); } assert.equal(buildDiag.backendBlocker.backend, "zero-macho64"); assert.equal(buildDiag.backendBlocker.stage, "buildability"); } await assertMachOObjectBuildabilityBlocked( "conformance/native/pass/macho-large-byte-slice-blocked.0", "macho-large-byte-slice.o", /constant start/, ); await assertMachOObjectBuildabilityBlocked( "conformance/native/pass/macho-nested-call-scratch-blocked.0", "macho-nested-call-scratch.o", /scratch spill capacity/, ); const machoOpenByteSliceFixture = "conformance/native/pass/macho-open-byte-slice.0"; const machoOpenByteSliceReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "darwin-arm64", machoOpenByteSliceFixture, ]); const machoOpenByteSliceReadinessBody = JSON.parse(machoOpenByteSliceReadiness.stdout); assert.equal(machoOpenByteSliceReadinessBody.ok, true); assert.equal(machoOpenByteSliceReadinessBody.diagnostics.length, 0); assert.equal(machoOpenByteSliceReadinessBody.targetReadiness.ok, true); assert.equal(machoOpenByteSliceReadinessBody.targetReadiness.buildable, true); assert.equal(machoOpenByteSliceReadinessBody.targetReadiness.backend, "zero-macho64"); const machoOpenByteSliceBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", machoOpenByteSliceFixture, "--out", `${outDir}/macho-open-byte-slice.o`, ]); const machoOpenByteSliceBuildBody = JSON.parse(machoOpenByteSliceBuild.stdout); assert.equal(machoOpenByteSliceBuildBody.compiler, "zero-macho64"); assert.equal(machoOpenByteSliceBuildBody.generatedCBytes, 0); assert.equal(machoOpenByteSliceBuildBody.objectBackend.objectEmission.path, "direct-macho64-object"); await assertMachOArm64Object(`${outDir}/macho-open-byte-slice.o`, "main"); const aarch64OpenSliceBoundsFixture = `${outDir}/aarch64-open-byte-slice-bounds.0`; await writeGraphFixture(aarch64OpenSliceBoundsFixture, `export c fn main() -> u32 { let words: [2]u16 = [1_u16, 2_u16] let suffix: Span = words[3_usize..] return (std.mem.len(suffix)) as u32 } `); await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", aarch64OpenSliceBoundsFixture, "--out", `${outDir}/aarch64-open-byte-slice-bounds.o`, ]); const aarch64OpenSliceBoundsBytes = await assertElfAarch64Object(`${outDir}/aarch64-open-byte-slice-bounds.o`, "main"); assert(hasAarch64CondBranch(aarch64OpenSliceBoundsBytes, 9)); assert(hasAarch64Instruction(aarch64OpenSliceBoundsBytes, 0xd4200000)); await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", aarch64OpenSliceBoundsFixture, "--out", `${outDir}/macho-open-byte-slice-bounds.o`, ]); const machoOpenSliceBoundsBytes = await assertMachOArm64Object(`${outDir}/macho-open-byte-slice-bounds.o`, "main"); assert(hasAarch64CondBranch(machoOpenSliceBoundsBytes, 9)); assert(hasAarch64Instruction(machoOpenSliceBoundsBytes, 0xd4200000)); const trapMessageFixture = `${outDir}/trap-index-message.0`; const trapMessageGraph = await writeGraphFixture(trapMessageFixture, `pub fn main(world: World) -> Void raises { var values: [4]u32 = [1, 2, 3, 4] var index: usize = 4 index = index + 1000 let v: u32 = values[index] if v == 1 { check world.out.write("unreachable\\n") } } `); if (runnableDirectTarget) { const trapMessageOut = `${outDir}/trap-index-message`; await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", runnableDirectTarget, trapMessageGraph, "--out", trapMessageOut]); const trapMessageRun = await execFileAsync(trapMessageOut, []).catch((error) => error); assert.notEqual(trapMessageRun.code ?? (trapMessageRun.signal ? 1 : 0), 0, "deliberate out-of-bounds index must abort"); assert.match(trapMessageRun.stderr ?? "", /trap: index out of bounds/); assert.equal(trapMessageRun.stdout ?? "", ""); } const x64OpenSliceBoundsFixture = `${outDir}/x64-open-u16-slice-bounds.0`; await writeGraphFixture(x64OpenSliceBoundsFixture, `export c fn main() -> u32 { let words: [2]u16 = [1_u16, 2_u16] let suffix: Span = words[3_usize..] return (std.mem.len(suffix)) as u32 } `); const x64SliceLenBoundsFixture = `${outDir}/x64-len-u16-slice-bounds.0`; await writeGraphFixture(x64SliceLenBoundsFixture, `export c fn main() -> u32 { let words: [2]u16 = [1_u16, 2_u16] return (std.mem.len(words[..3_usize])) as u32 } `); await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", x64SliceLenBoundsFixture, "--out", `${outDir}/aarch64-len-u16-slice-bounds.o`, ]); const aarch64LenSliceBoundsBytes = await assertElfAarch64Object(`${outDir}/aarch64-len-u16-slice-bounds.o`, "main"); assert(hasAarch64CondBranch(aarch64LenSliceBoundsBytes, 9)); assert(hasAarch64Instruction(aarch64LenSliceBoundsBytes, 0xd4200000)); await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", x64SliceLenBoundsFixture, "--out", `${outDir}/macho-len-u16-slice-bounds.o`, ]); const machoLenSliceBoundsBytes = await assertMachOArm64Object(`${outDir}/macho-len-u16-slice-bounds.o`, "main"); assert(hasAarch64CondBranch(machoLenSliceBoundsBytes, 9)); assert(hasAarch64Instruction(machoLenSliceBoundsBytes, 0xd4200000)); async function assertX64SliceBoundsObject(fixture, name) { const elfPath = `${outDir}/${name}-linux.o`; await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "linux-musl-x64", fixture, "--out", elfPath]); assertX64SliceBoundsTrapBytes((await assertElf64Object(elfPath, "main")).bytes); const machoPath = `${outDir}/${name}-macho-x64.o`; await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "darwin-x64", fixture, "--out", machoPath]); assertX64SliceBoundsTrapBytes(await assertMachOX64Object(machoPath, "main")); const coffPath = `${outDir}/${name}-coff.obj`; await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "win32-x64.exe", fixture, "--out", coffPath]); assertX64SliceBoundsTrapBytes(await assertCoffX64Object(coffPath, "main")); } await assertX64SliceBoundsObject(x64OpenSliceBoundsFixture, "x64-open-u16-slice-bounds"); await assertX64SliceBoundsObject(x64SliceLenBoundsFixture, "x64-len-u16-slice-bounds"); const x64U16RecordFieldFixture = `${outDir}/x64-u16-record-field.0`; await writeGraphFixture(x64U16RecordFieldFixture, `type Holder { values: [3]u16, } export c fn main() -> u32 { var holder: Holder = Holder { values: [10_u16, 20_u16, 30_u16] } if holder.values[0] == 10_u16 && holder.values[1] == 20_u16 && holder.values[2] == 30_u16 { return 1 } return 0 } `); const x64U16RecordFieldElfPath = `${outDir}/x64-u16-record-field-linux.o`; await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "linux-musl-x64", x64U16RecordFieldFixture, "--out", x64U16RecordFieldElfPath]); assertX64U16RecordFieldBytes((await assertElf64Object(x64U16RecordFieldElfPath, "main")).bytes); const x64U16RecordFieldMachOPath = `${outDir}/x64-u16-record-field-macho-x64.o`; await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "darwin-x64", x64U16RecordFieldFixture, "--out", x64U16RecordFieldMachOPath]); assertX64U16RecordFieldBytes(await assertMachOX64Object(x64U16RecordFieldMachOPath, "main")); async function assertAArch64ObjectBuildabilityBlocked(target, backend, outName, expectedMessage) { const fixture = "conformance/native/pass/macho-nested-call-scratch-blocked.0"; const readiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", target, fixture, ]); const readinessBody = JSON.parse(readiness.stdout); assert.equal(readinessBody.ok, true); assert.equal(readinessBody.diagnostics.length, 0); assert.equal(readinessBody.targetReadiness.ok, false); assert.equal(readinessBody.targetReadiness.buildable, false); assert.equal(readinessBody.targetReadiness.languageOk, true); assert.equal(readinessBody.targetReadiness.emit, "obj"); assert.equal(readinessBody.targetReadiness.target, target); assert.equal(readinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.backend, backend); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "buildability"); assert.match(readinessBody.targetReadiness.diagnostics[0].message, expectedMessage); const build = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", target, fixture, "--out", `${outDir}/${outName}`, ]).catch((error) => error); assert.notEqual(build.code, 0); const buildBody = JSON.parse(build.stdout); const readinessDiag = readinessBody.targetReadiness.diagnostics[0]; const buildDiag = buildBody.diagnostics[0]; for (const key of ["code", "path", "line", "column", "length", "expected", "actual", "help"]) { assert.equal(buildDiag[key], readinessDiag[key]); } assert.equal(buildDiag.backendBlocker.backend, backend); assert.equal(buildDiag.backendBlocker.stage, "buildability"); } await assertAArch64ObjectBuildabilityBlocked("linux-arm64", "zero-elf-aarch64", "elf-aarch64-nested-call-scratch.o", /scratch spill capacity/); await assertAArch64ObjectBuildabilityBlocked("win32-arm64.exe", "zero-coff-aarch64", "coff-aarch64-nested-call-scratch.obj", /scratch spill capacity/); const machoBoolArraysBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", "conformance/native/pass/bool-arrays.0", "--out", `${outDir}/macho-bool-arrays.o`, ]); const machoBoolArraysBody = JSON.parse(machoBoolArraysBuild.stdout); assert.equal(machoBoolArraysBody.compiler, "zero-macho64"); assert.equal(machoBoolArraysBody.generatedCBytes, 0); assert.equal(machoBoolArraysBody.objectBackend.objectEmission.path, "direct-macho64-object"); const directCallArm64ObjReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "linux-arm64", "examples/direct-call-add.0", ]); const directCallArm64ObjReadinessBody = JSON.parse(directCallArm64ObjReadiness.stdout); assert.equal(directCallArm64ObjReadinessBody.ok, true); assert.equal(directCallArm64ObjReadinessBody.diagnostics.length, 0); assert.equal(directCallArm64ObjReadinessBody.targetReadiness.ok, true); assert.equal(directCallArm64ObjReadinessBody.targetReadiness.buildable, true); assert.equal(directCallArm64ObjReadinessBody.targetReadiness.backend, "zero-elf-aarch64"); const directCallArm64ObjBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", "examples/direct-call-add.0", "--out", `${outDir}/direct-call-add-arm64.o`, ]); const directCallArm64ObjBuildBody = JSON.parse(directCallArm64ObjBuild.stdout); assert.equal(directCallArm64ObjBuildBody.compiler, "zero-elf-aarch64"); assert.equal(directCallArm64ObjBuildBody.generatedCBytes, 0); assert.equal(directCallArm64ObjBuildBody.objectBackend.objectEmission.path, "direct-elf-aarch64-object"); await assertElfAarch64Object(`${outDir}/direct-call-add-arm64.o`, "main"); const arm64ProcDynamicViewsSource = `${outDir}/aarch64-proc-dynamic-byte-view-spawn.0`; const arm64ProcDynamicViewsObj = `${outDir}/aarch64-proc-dynamic-byte-view-spawn.o`; await writeGraphFixture(arm64ProcDynamicViewsSource, `fn programName() -> String { return "sh" } fn childArgs() -> Span { return std.mem.span("-c\\ntrue") } fn cwdName() -> String { return "." } fn envBlock() -> Span { return std.mem.span("ZERO_AARCH64_PROC=1") } fn childCommand() -> String { return "sh -c true" } export c fn main() -> i32 { let status: ProcStatus = std.proc.spawnInheritArgs(programName(), childArgs(), cwdName(), envBlock()) let child: ProcChild = std.proc.spawnChildArgs(programName(), childArgs(), cwdName(), envBlock()) let child_env: ProcChild = std.proc.spawnChildInEnv(childCommand(), cwdName(), envBlock()) let pty_child: ProcChild = std.pty.spawnArgs(programName(), childArgs(), cwdName(), envBlock()) return std.proc.exitCode(status) + std.proc.pid(child) + std.proc.pid(child_env) + std.proc.pid(pty_child) } `); const arm64ProcDynamicViewsBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", arm64ProcDynamicViewsSource, "--out", arm64ProcDynamicViewsObj, ]); const arm64ProcDynamicViewsBuildBody = JSON.parse(arm64ProcDynamicViewsBuild.stdout); assert.equal(arm64ProcDynamicViewsBuildBody.compiler, "zero-elf-aarch64"); assert.equal(arm64ProcDynamicViewsBuildBody.objectBackend.objectEmission.path, "direct-elf-aarch64-object"); const arm64ProcDynamicViewsBytes = await assertElfAarch64Object(arm64ProcDynamicViewsObj, "main"); assert(countAarch64InstructionSequence(arm64ProcDynamicViewsBytes, aarch64ByteViewReloadSequence(4)) >= 3); let arm64NestedIndexExpr = "values[idx]"; for (let i = 0; i < 32; i++) arm64NestedIndexExpr = `(0_u32 + ${arm64NestedIndexExpr})`; const arm64NestedIndexFixture = `${outDir}/aarch64-nested-index-scratch-blocked.0`; await writeGraphFixture(arm64NestedIndexFixture, `export c fn main() -> u32 { let values: [1]u32 = [7] let idx: u32 = 0_u32 return ${arm64NestedIndexExpr} } `); async function assertArm64NestedScratchBlocked(fixture, expectedMessage, outPrefix) { for (const blocked of [["linux-arm64", "zero-elf-aarch64", "linux.o"], ["darwin-arm64", "zero-macho64", "macho.o"], ["win32-arm64.exe", "zero-coff-aarch64", "coff.obj"]]) { const readiness = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "--target", blocked[0], fixture]); const readinessBody = JSON.parse(readiness.stdout); assert.equal(readinessBody.ok, true); assert.equal(readinessBody.targetReadiness.ok, false); assert.equal(readinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.backend, blocked[1]); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "buildability"); assert.match(readinessBody.targetReadiness.diagnostics[0].message, expectedMessage); const build = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", blocked[0], fixture, "--out", `${outDir}/${outPrefix}-${blocked[2]}`]).catch((error) => error); assert.notEqual(build.code, 0); assert.equal(JSON.parse(build.stdout).diagnostics[0].backendBlocker.stage, "buildability"); } } await assertArm64NestedScratchBlocked(arm64NestedIndexFixture, /indexed load exceeds scratch register spill capacity/, "aarch64-nested-index"); let arm64NestedLenExpr = "((std.mem.len(text[start..end])) as u32)"; for (let i = 0; i < 32; i++) arm64NestedLenExpr = `(0_u32 + ${arm64NestedLenExpr})`; const arm64NestedLenFixture = `${outDir}/aarch64-nested-len-scratch-blocked.0`; await writeGraphFixture(arm64NestedLenFixture, `export c fn main() -> u32 { let text: String = "abcdef" let start: usize = 1 let end: usize = 4 return ${arm64NestedLenExpr} } `); await assertArm64NestedScratchBlocked(arm64NestedLenFixture, /byte-view length exceeds scratch register spill capacity/, "aarch64-nested-len"); let arm64NestedDynamicStartLenExpr = "((std.mem.len(text[(start + 0_usize)..end])) as u32)"; for (let i = 0; i < 31; i++) arm64NestedDynamicStartLenExpr = `(0_u32 + ${arm64NestedDynamicStartLenExpr})`; const arm64NestedDynamicStartLenFixture = `${outDir}/aarch64-nested-dynamic-start-len-scratch-blocked.0`; await writeGraphFixture(arm64NestedDynamicStartLenFixture, `export c fn main() -> u32 { let text: String = "abcdef" let start: usize = 1 let end: usize = 4 return ${arm64NestedDynamicStartLenExpr} } `); await assertArm64NestedScratchBlocked(arm64NestedDynamicStartLenFixture, /byte-view length exceeds scratch register spill capacity/, "aarch64-nested-dynamic-start-len"); let arm64NestedEndLenExpr = "((std.mem.len(text[1..(end + 0_usize)])) as u32)"; for (let i = 0; i < 32; i++) arm64NestedEndLenExpr = `(0_u32 + ${arm64NestedEndLenExpr})`; const arm64NestedEndLenFixture = `${outDir}/aarch64-nested-end-len-scratch-blocked.0`; await writeGraphFixture(arm64NestedEndLenFixture, `export c fn main() -> u32 { let text: String = "abcdef" let end: usize = 4 return ${arm64NestedEndLenExpr} } `); await assertArm64NestedScratchBlocked(arm64NestedEndLenFixture, /byte-view length exceeds scratch register spill capacity/, "aarch64-nested-end-len"); let arm64NestedDynamicEqlExpr = "std.mem.eqlBytes(text[(start + (0_usize + 0_usize))..end], text[(start + (0_usize + 0_usize))..end])"; for (let i = 0; i < 29; i++) arm64NestedDynamicEqlExpr = `(true == ${arm64NestedDynamicEqlExpr})`; const arm64NestedDynamicEqlFixture = `${outDir}/aarch64-nested-dynamic-eql-scratch-blocked.0`; await writeGraphFixture(arm64NestedDynamicEqlFixture, `export c fn main() -> Bool { let text: String = "abcdef" let start: usize = 1 let end: usize = 4 return ${arm64NestedDynamicEqlExpr} } `); await assertArm64NestedScratchBlocked(arm64NestedDynamicEqlFixture, /byte-view equality exceeds scratch register spill capacity/, "aarch64-nested-dynamic-eql"); let arm64WorldWriteSliceStart = "(start + 0_usize)"; for (let i = 0; i < 31; i++) arm64WorldWriteSliceStart = `(0_usize + ${arm64WorldWriteSliceStart})`; const arm64WorldWriteFixture = `${outDir}/aarch64-world-write-dynamic-slice-scratch-blocked.0`; await writeGraphFixture(arm64WorldWriteFixture, `pub fn main(world: World) -> Void raises { let text: String = "abcdef" let start: usize = 1 check world.out.write(text[${arm64WorldWriteSliceStart}..6]) } `); async function assertArm64WorldWriteScratchBlocked(fixture, expectedMessage, outPrefix) { for (const blocked of [["linux-musl-arm64", "zero-elf-aarch64-exe", "linux"], ["win32-arm64.exe", "zero-coff-aarch64-exe", "coff.exe"]]) { const readiness = await execFileAsync(zero, ["check", "--json", "--emit", "exe", "--target", blocked[0], fixture]); const readinessBody = JSON.parse(readiness.stdout); assert.equal(readinessBody.ok, true); assert.equal(readinessBody.targetReadiness.ok, false); assert.equal(readinessBody.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.backend, blocked[1]); assert.equal(readinessBody.targetReadiness.diagnostics[0].backendBlocker.stage, "buildability"); assert.match(readinessBody.targetReadiness.diagnostics[0].message, expectedMessage); const build = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", blocked[0], fixture, "--out", `${outDir}/${outPrefix}-${blocked[2]}`]).catch((error) => error); assert.notEqual(build.code, 0); const buildDiag = JSON.parse(build.stdout).diagnostics[0]; assert.equal(buildDiag.backendBlocker.backend, blocked[1]); assert.equal(buildDiag.backendBlocker.stage, "buildability"); assert.match(buildDiag.message, expectedMessage); } } await assertArm64WorldWriteScratchBlocked(arm64WorldWriteFixture, /expression nesting exceeds scratch register spill capacity/, "aarch64-world-write-dynamic-slice"); let arm64WorldWriteSliceEnd = "(end + 0_usize)"; for (let i = 0; i < 32; i++) arm64WorldWriteSliceEnd = `(0_usize + ${arm64WorldWriteSliceEnd})`; const arm64WorldWriteEndFixture = `${outDir}/aarch64-world-write-dynamic-end-scratch-blocked.0`; await writeGraphFixture(arm64WorldWriteEndFixture, `pub fn main(world: World) -> Void raises { let text: String = "abcdef" let end: usize = 6 check world.out.write(text[1..${arm64WorldWriteSliceEnd}]) } `); await assertArm64WorldWriteScratchBlocked(arm64WorldWriteEndFixture, /expression nesting exceeds scratch register spill capacity/, "aarch64-world-write-dynamic-end"); const arm64PrivateHelperObj = `${outDir}/aarch64-private-helper-ignored.o`; await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", "conformance/native/pass/aarch64-private-helper-ignored.0", "--out", arm64PrivateHelperObj, ]); const arm64PrivateHelperBytes = await assertElfAarch64Object(arm64PrivateHelperObj, "main"); assert(arm64PrivateHelperBytes.includes(Buffer.from([0x40, 0x05, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6]))); const arm64CompareSource = `${outDir}/aarch64-typed-compare.0`; const arm64CompareObj = `${outDir}/aarch64-typed-compare.o`; await writeGraphFixture(arm64CompareSource, `export c fn main() -> u32 { let large: u32 = 4294967295 if large > 0_u32 { return 7 } return 3 } export c fn wide_guard() -> u32 { let wide: u64 = 4294967296 if wide != 0_u64 { return 9 } return 4 } `); await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "linux-arm64", arm64CompareSource, "--out", arm64CompareObj, ]); const arm64CompareBytes = await readFile(arm64CompareObj); assert(hasAarch64CondBranch(arm64CompareBytes, 9)); assert(hasAarch64Instruction(arm64CompareBytes, 0xeb09011f)); const memoryPackageMachOReadiness = await execFileAsync(zero, [ "check", "--json", "--emit", "obj", "--target", "darwin-arm64", "examples/memory-package", ]); const memoryPackageMachOReadinessBody = JSON.parse(memoryPackageMachOReadiness.stdout); assert.equal(memoryPackageMachOReadinessBody.ok, true); assert.equal(memoryPackageMachOReadinessBody.diagnostics.length, 0); assert.equal(memoryPackageMachOReadinessBody.targetReadiness.ok, true); assert.equal(memoryPackageMachOReadinessBody.targetReadiness.buildable, true); assert.equal(memoryPackageMachOReadinessBody.targetReadiness.backend, "zero-macho64"); assert.equal(memoryPackageMachOReadinessBody.targetReadiness.diagnostics.length, 0); const memoryPackageMachOObj = `${outDir}/memory-package-macho.o`; const memoryPackageMachOBuild = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", "examples/memory-package", "--out", memoryPackageMachOObj, ]); const memoryPackageMachOBuildBody = JSON.parse(memoryPackageMachOBuild.stdout); assert.equal(memoryPackageMachOBuildBody.compiler, "zero-macho64"); assert.equal(memoryPackageMachOBuildBody.generatedCBytes, 0); assert.equal(memoryPackageMachOBuildBody.objectBackend.objectEmission.path, "direct-macho64-object"); await assertMachOArm64Object(memoryPackageMachOObj, "main"); async function assertAgentSurfaceOwnedDropUnsupported(target, emit, outName, expectedPattern, expectedObjectFormat, expectedBackend, options = {}) { const extraArgs = options.extraArgs ?? []; const build = await execFileAsync(zero, [ "build", "--json", "--emit", emit, "--target", target, ...extraArgs, "conformance/agent-surface/fixtures/owned-drop-direct-backend-unsupported.0", "--out", `${outDir}/${outName}`, ]).catch((error) => error); assert.notEqual(build.code, 0); const body = JSON.parse(build.stdout); const diagnostic = body.diagnostics[0]; assert.equal(diagnostic.code, "BLD004"); assert.match(diagnostic.expected, expectedPattern); assert.equal(diagnostic.actual, "owned"); assert.deepEqual(diagnostic.backendBlocker, { target, objectFormat: expectedObjectFormat, backend: expectedBackend, stage: "lower", unsupportedFeature: "owned", }); } await assertAgentSurfaceOwnedDropUnsupported("linux-musl-x64", "obj", "agent-surface-owned-drop-elf.o", /typed program graph MIR subset/, "elf", "zero-elf64-exe"); await assertAgentSurfaceOwnedDropUnsupported("darwin-arm64", "obj", "agent-surface-owned-drop-macho.o", /typed program graph MIR subset/, "macho", "zero-macho64-exe"); await assertAgentSurfaceOwnedDropUnsupported("win32-x64.exe", "obj", "agent-surface-owned-drop-coff.obj", /typed program graph MIR subset/, "coff", "zero-coff-x64-exe"); const mismatchedDirectEmitter = await execFileAsync(zero, [ "build", "--json", "--emit", "obj", "--target", "darwin-arm64", "--backend", "zero-elf64", "examples/add.0", "--out", `${outDir}/direct-emitter-mismatch.o`, ]).catch((error) => error); assert.notEqual(mismatchedDirectEmitter.code, 0); const mismatchedDirectEmitterBody = JSON.parse(mismatchedDirectEmitter.stdout); assert.equal(mismatchedDirectEmitterBody.diagnostics[0].code, "BLD004"); assert.equal(mismatchedDirectEmitterBody.diagnostics[0].actual, "--backend zero-elf64"); assert.deepEqual(mismatchedDirectEmitterBody.diagnostics[0].backendBlocker, { target: "darwin-arm64", objectFormat: "macho", backend: "zero-elf64", stage: "target-selection", unsupportedFeature: "requested direct emitter does not match target", }); const commonPassFixtures = [ ["conformance/common/pass/array-sum-min-max.0", "common-array-sum-min-max", { stdout: "array sum min max ok\n" }], ["conformance/common/pass/bytes-reverse.0", "common-bytes-reverse", { stdout: "bytes reverse ok\n" }], ["conformance/common/pass/cli-args.0", "common-cli-args", { stdout: "alpha\n", args: ["alpha", "beta"] }], ["conformance/common/pass/count-words-lines.0", "common-count-words-lines", { stdout: "count words lines ok\n" }], ["conformance/common/pass/factorial.0", "common-factorial", { stdout: "factorial ok\n" }], ["conformance/common/pass/fib-iterative.0", "common-fib-iterative", { stdout: "fib iterative ok\n" }], ["conformance/common/pass/fib-recursive.0", "common-fib-recursive", { stdout: "fib recursive ok\n" }], ["conformance/common/pass/file-copy.0", "common-file-copy", { stdout: "file copy ok\n", file: { name: "common-file-copy-output.txt", text: "zero file copy\n" } }], ["conformance/common/pass/gcd.0", "common-gcd", { stdout: "gcd ok\n" }], ["conformance/common/pass/json-roundtrip.0", "common-json-roundtrip", { stdout: "json roundtrip ok\n" }], ["conformance/common/pass/palindrome.0", "common-palindrome", { stdout: "palindrome ok\n" }], ["conformance/common/pass/prime.0", "common-prime", { stdout: "prime ok\n" }], ["conformance/common/pass/sieve-small.0", "common-sieve-small", { stdout: "sieve small ok\n" }], ["conformance/common/pass/sort-small.0", "common-sort-small", { stdout: "sort small ok\n" }], ["conformance/common/pass/string-search.0", "common-string-search", { stdout: "string search ok\n" }], ["conformance/common/pass/word-reverse.0", "common-word-reverse", { stdout: "word reverse ok\n" }], ]; for (const [fixture, name, expected] of commonPassFixtures) { const check = await execFileAsync(zero, ["check", "--json", fixture]); assert.equal(JSON.parse(check.stdout).ok, true); const graph = await execFileAsync(zero, ["inspect", "--json", fixture]); const graphBody = JSON.parse(graph.stdout); assert.equal(graphBody.graph.artifact, fixture.replace(/\.0$/, ".graph")); assert(graphBody.sourceFiles.includes(fixture) || graphBody.sourceFiles.includes(fixture.split("/").at(-1))); const size = await execFileAsync(zero, ["size", "--json", fixture]); assert.equal(JSON.parse(size.stdout).schemaVersion, 1); await assertCommonRuntimeOrUnsupported(fixture, name, expected); } const commonUnsupportedTarget = await execFileAsync(zero, ["check", "--json", "--target", "linux-musl-x64", "conformance/common/fail/unsupported-target-feature.0"]).catch((error) => error); assert.notEqual(commonUnsupportedTarget.code, 0); assert.equal(JSON.parse(commonUnsupportedTarget.stdout).diagnostics[0].code, "TAR002"); const compileTimeJson = await execFileAsync(zero, ["check", "--json", "conformance/native/pass/compile-time-v1.0"]); const compileTimeBody = JSON.parse(compileTimeJson.stdout); assert.equal(compileTimeBody.ok, true); assert.equal(compileTimeBody.compileTime.deterministic, true); assert.equal(compileTimeBody.compileTime.sandbox.filesystem, "denied"); assert.equal(compileTimeBody.compileTime.sandbox.network, "denied"); assert.equal(compileTimeBody.compileTime.limits.maxDepth, 64); assert.equal(compileTimeBody.compileTime.limits.maxSteps, 1024); assert.equal(compileTimeBody.compileTime.cacheKeyInputs.algorithm, "fnv1a64-zero-meta-v1"); assert.ok(compileTimeBody.compileTime.cacheKeyInputs.sourceHash); assert.ok(compileTimeBody.compileTime.meta.supportedFacts.includes("target.abi")); assert.ok(compileTimeBody.compileTime.meta.supportedFacts.includes("fieldType")); assert.ok(compileTimeBody.compileTime.meta.supportedFacts.includes("hasEnumCase")); assert.ok(compileTimeBody.compileTime.staticValues.supported.includes("Bool")); assert.ok(compileTimeBody.compileTime.staticValues.supported.includes("enum")); assert.equal(compileTimeBody.compileTime.staticValues.runtimeRegistries, false); assert.equal(compileTimeBody.compileTime.staticValues.reflectionTables, false); assert.equal(compileTimeBody.compileTime.reflection.compileTimeOnly, true); assert.equal(compileTimeBody.compileTime.typedBuilders.status, "limited-v1"); assert.equal(compileTimeBody.compileTime.typedBuilders.rawTokenStrings, false); assert.equal(compileTimeBody.safetyFacts.schemaVersion, 1); assert.equal(compileTimeBody.safetyFacts.bounds.runtimeTraps, true); assert.equal(compileTimeBody.safetyFacts.bounds.optimizerElision, false); assert.equal(compileTimeBody.safetyFacts.overflow.runtimeArithmetic, "unchecked-machine-wrap"); assert.equal(compileTimeBody.safetyFacts.overflow.unchecked, true); assert.equal(compileTimeBody.safetyFacts.initialization.locals, "initializer-required"); assert.equal(compileTimeBody.safetyFacts.initialization.maybePayloadReads, "guard-checked"); assert.equal(compileTimeBody.safetyFacts.aliasing.mutableAliases, "diagnostic"); assert.equal(compileTimeBody.safetyFacts.mir.invalidMemoryContractsBlockEmission, true); const compileTimeGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/native/pass/compile-time-v1.0"]); const compileTimeGraphBody = JSON.parse(compileTimeGraph.stdout); assert.equal(compileTimeGraphBody.compileTime.deterministic, true); assert.equal(compileTimeGraphBody.safetyFacts.profileKey, "small"); assert.equal(compileTimeGraphBody.safetyFacts.lifetimes.escapedLocalBorrow, "diagnostic"); const readGateGraph = compileTimeGraphBody.functions.find((item) => item.name === "readGate"); assert.ok(readGateGraph.staticParams.some((item) => item.name === "enabledFlag" && item.kind === "bool")); assert.ok(readGateGraph.staticParams.some((item) => item.name === "selectedMode" && item.kind === "enum")); const gateGraph = compileTimeGraphBody.shapes.find((item) => item.name === "Gate"); assert.ok(gateGraph.staticParams.some((item) => item.name === "enabledFlag" && item.kind === "bool")); assert.ok(gateGraph.staticParams.some((item) => item.name === "selectedMode" && item.kind === "enum")); const fastCheck = await execFileAsync(zero, ["check", "--json", "--profile", "fast", "examples/hello.0"]); const fastCheckBody = JSON.parse(fastCheck.stdout); assert.equal(fastCheckBody.artifact, "examples/hello.graph"); assert.equal(fastCheckBody.canonicalSource, false); assert.equal(fastCheckBody.check.lowering, "graph-native-check"); assert.equal(fastCheckBody.safetyFacts.profile, "release-fast"); assert.equal(fastCheckBody.safetyFacts.profileKey, "fast"); const fastGraph = await execFileAsync(zero, ["inspect", "--json", "--profile", "fast", "examples/hello.0"]); const fastGraphBody = JSON.parse(fastGraph.stdout); assert.equal(fastGraphBody.packageCache.profile, "fast"); assert.equal(fastGraphBody.incrementalInvalidation.profileDependency, "fast"); assert.equal(fastGraphBody.safetyFacts.profile, "release-fast"); assert.equal(fastGraphBody.safetyFacts.profileKey, "fast"); const buildJsonM6 = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", "linux-musl-x64", "--release", "tiny", "examples/hello.0", "--out", `${outDir}/m6-hello`]); const buildJsonM6Body = JSON.parse(buildJsonM6.stdout); assert.equal(buildJsonM6Body.legacy, false); assert.equal(buildJsonM6Body.legacyBackend, null); assert.equal(buildJsonM6Body.generatedCBytes, 0); assert.equal(buildJsonM6Body.profileSemantics.canonical, "tiny"); assert.equal(buildJsonM6Body.profileSemantics.panicPolicy, "abort"); assert.equal(buildJsonM6Body.profileSemantics.runtimeMetadataPolicy, "minimum"); assert.equal(buildJsonM6Body.profileSemantics.profileKey, "tiny"); assert.equal(buildJsonM6Body.profileSemantics.unwindPolicy, "no-unwind-abort"); assert.equal(buildJsonM6Body.profileSemantics.boundsPolicy, "checked"); assert.equal(buildJsonM6Body.profileSemantics.overflowPolicy, "literal-range-checked-runtime-unchecked"); assert.equal(buildJsonM6Body.profileSemantics.profileBudget.generatedCBytes, 0); assert.equal(buildJsonM6Body.safetyFacts.profile, "tiny"); assert.equal(buildJsonM6Body.safetyFacts.bounds.policy, "checked"); assert.equal(buildJsonM6Body.safetyFacts.bounds.optimizerElision, false); assert.equal(buildJsonM6Body.safetyFacts.overflow.policy, "literal-range-checked-runtime-unchecked"); assert.equal(buildJsonM6Body.safetyFacts.overflow.integerLiterals, "range-checked"); assert.equal(buildJsonM6Body.safetyFacts.ownership.useAfterMove, "diagnostic"); assert.equal(buildJsonM6Body.profileBudget.helperBudgetPolicy, "pay-as-used-minimum-runtime"); assert(buildJsonM6Body.profileCatalog.some((item) => item.canonical === "debug" && item.debugInfo === true)); assert(buildJsonM6Body.profileCatalog.some((item) => item.canonical === "release-fast" && item.boundsPolicy === "checked")); assert(buildJsonM6Body.profileCatalog.some((item) => item.canonical === "audit" && item.runtimeMetadataPolicy === "maximum")); assert.equal(buildJsonM6Body.objectBackend.internalIr.callRepresentation, "same-object direct calls for supported direct subsets"); assert.equal(buildJsonM6Body.objectBackend.objectEmission.path, "direct-elf64-exe"); assert.equal(buildJsonM6Body.objectBackend.objectEmission.symbols, true); assert.ok(buildJsonM6Body.objectBackend.linking.linkerFlavor); assert.equal(buildJsonM6Body.objectBackend.linking.stripArtifacts, false); for (const [requestedProfile, canonicalProfile, profileKey] of [ ["debug", "debug", "debug"], ["fast", "release-fast", "fast"], ["small", "release-small", "small"], ]) { const profileBuild = await execFileAsync(zero, ["build", "--json", "--profile", requestedProfile, "--target", "linux-musl-x64", "examples/hello.0", "--out", `${outDir}/m25-${requestedProfile}-hello`]); const profileBody = JSON.parse(profileBuild.stdout); assert.equal(profileBody.generatedCBytes, 0); assert.equal(profileBody.profileSemantics.canonical, canonicalProfile); assert.equal(profileBody.profileSemantics.profileKey, profileKey); assert.equal(profileBody.profileSemantics.boundsPolicy, "checked"); assert.equal(profileBody.profileSemantics.overflowPolicy, "literal-range-checked-runtime-unchecked"); assert.equal(profileBody.profileSemantics.profileBudget.generatedCBytes, 0); assert.equal(profileBody.safetyFacts.profile, canonicalProfile); assert.equal(profileBody.safetyFacts.profileKey, profileKey); assert.equal(profileBody.safetyFacts.bounds.optimizerElision, false); assert.equal(profileBody.profileBudget.cBridgeFallback, false); } const profileSize = await execFileAsync(zero, ["size", "--json", "--profile", "debug", "--target", "linux-musl-x64", "examples/hello.0"]); const profileSizeBody = JSON.parse(profileSize.stdout); assert.equal(profileSizeBody.generatedCBytes, 0); assert.equal(profileSizeBody.graph.artifact, "examples/hello.graph"); assert.equal(profileSizeBody.graph.lowering, "mapped-final-mir"); assert.equal(profileSizeBody.profileSemantics.profileKey, "debug"); assert.equal(profileSizeBody.safetyFacts.profileKey, "debug"); assert.equal(profileSizeBody.safetyFacts.uncheckedSurfaces[0].surface, "C imports"); assert.equal(profileSizeBody.sizeBreakdown.profileKey, "debug"); assert(Array.isArray(profileSizeBody.sizeBreakdown.functions)); assert(profileSizeBody.sizeBreakdown.sections.some((item) => item.name === "text" && item.retainedBy.includes("retained functions"))); assert(Array.isArray(profileSizeBody.sizeBreakdown.literals.items)); assert(Array.isArray(profileSizeBody.sizeBreakdown.stdlibHelpers)); assert(Array.isArray(profileSizeBody.sizeBreakdown.imports)); assert(Array.isArray(profileSizeBody.sizeBreakdown.runtimeShims)); assert(profileSizeBody.sizeBreakdown.debugMetadata.bytes > 0); assert(profileSizeBody.compilerCaches.some((item) => item.name === "mappedFinalMir" && item.sourceKind === "program-graph" && item.programReconstructed === false)); assert(profileSizeBody.retentionReasons.some((item) => item.kind === "debugMetadata")); assert(profileSizeBody.optimizationHints.some((item) => item.id === "profile-debug-metadata")); assert.equal(profileSizeBody.profileBudget.debugMetadataAllowed, true); const directObjOut = `${outDir}/direct-obj-add.o`; const directObjJson = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "linux-musl-x64", "examples/direct-obj-add.0", "--out", directObjOut]); const directObjBody = JSON.parse(directObjJson.stdout); assert.equal(directObjBody.emit, "obj"); assert.equal(directObjBody.compiler, "zero-elf64"); assert.equal(directObjBody.generatedCBytes, 0); assert(directObjBody.loweredIrBytes > 0); assert.equal(directObjBody.objectBackend.objectEmission.path, "direct-elf64-object"); await assertElf64Object(directObjOut, "main"); const directI64ObjOut = `${outDir}/direct-i64-return.o`; const directI64ObjJson = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "linux-musl-x64", "examples/direct-i64-return.0", "--out", directI64ObjOut]); const directI64ObjBody = JSON.parse(directI64ObjJson.stdout); const directI64ObjBytes = await readFile(directI64ObjOut); assert.equal(directI64ObjBody.emit, "obj"); assert.equal(directI64ObjBody.compiler, "zero-elf64"); assert.equal(directI64ObjBody.generatedCBytes, 0); assert.equal(directI64ObjBody.objectBackend.objectEmission.path, "direct-elf64-object"); assert(directI64ObjBytes.includes(Buffer.from([0x48, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]))); assert(directI64ObjBytes.includes(Buffer.from([0x48, 0x01, 0xc8]))); const directWideMainSource = `${outDir}/direct-exe-wide-main.0`; const directWideMainOut = `${outDir}/direct-exe-wide-main`; await writeGraphFixture(directWideMainSource, `export c fn main() -> usize { return 8589934590 } `); const directWideMainJson = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", "linux-musl-x64", directWideMainSource, "--out", directWideMainOut]); const directWideMainBody = JSON.parse(directWideMainJson.stdout); const directWideMainBytes = await readFile(directWideMainOut); assert.equal(directWideMainBody.compiler, "zero-elf64"); assert.equal(directWideMainBody.objectBackend.objectEmission.path, "direct-elf64-exe"); assert(!directWideMainBytes.includes(Buffer.from([0x48, 0xc1, 0xe9, 0x20]))); assert(directWideMainBytes.includes(Buffer.from([0x89, 0xc7, 0xb8, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x05]))); const directI64MainSource = `${outDir}/direct-exe-i64-main.0`; const directI64MainOut = `${outDir}/direct-exe-i64-main`; await writeGraphFixture(directI64MainSource, `export c fn main() -> i64 { return 8589934590_i64 } `); const directI64MainJson = await execFileAsync(zero, ["build", "--json", "--emit", "exe", "--target", "linux-musl-x64", directI64MainSource, "--out", directI64MainOut]); const directI64MainBody = JSON.parse(directI64MainJson.stdout); assert.equal(directI64MainBody.compiler, "zero-elf64"); assert.equal(directI64MainBody.objectBackend.objectEmission.path, "direct-elf64-exe"); const directMachOU64LiteralSource = `${outDir}/direct-macho-u64-literal.0`; const directMachOU64LiteralOut = `${outDir}/direct-macho-u64-literal.o`; await writeGraphFixture(directMachOU64LiteralSource, `export c fn main() -> u64 { let value: u64 = 4294967296 return value } `); const directMachOU64LiteralReadinessJson = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "--target", "darwin-arm64", directMachOU64LiteralSource]); const directMachOU64LiteralReadinessBody = JSON.parse(directMachOU64LiteralReadinessJson.stdout); assert.equal(directMachOU64LiteralReadinessBody.targetReadiness.buildable, true); const directMachOU64LiteralJson = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "darwin-arm64", directMachOU64LiteralSource, "--out", directMachOU64LiteralOut]); const directMachOU64LiteralBody = JSON.parse(directMachOU64LiteralJson.stdout); const directMachOU64LiteralBytes = await readFile(directMachOU64LiteralOut); assert.equal(directMachOU64LiteralBody.compiler, "zero-macho64"); assert.equal(directMachOU64LiteralBody.objectBackend.objectEmission.path, "direct-macho64-object"); assert(directMachOU64LiteralBytes.includes(Buffer.from([0x28, 0x00, 0xc0, 0xf2]))); const directMachOU64DivSource = `${outDir}/direct-macho-u64-div.0`; const directMachOU64DivOut = `${outDir}/direct-macho-u64-div.o`; await writeGraphFixture(directMachOU64DivSource, `export c fn main(a: u64, b: u64) -> u64 { return a / b } `); const directMachOU64DivJson = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "darwin-arm64", directMachOU64DivSource, "--out", directMachOU64DivOut]); const directMachOU64DivBody = JSON.parse(directMachOU64DivJson.stdout); const directMachOU64DivBytes = await readFile(directMachOU64DivOut); assert.equal(directMachOU64DivBody.compiler, "zero-macho64"); assert.equal(directMachOU64DivBody.objectBackend.objectEmission.path, "direct-macho64-object"); assert(directMachOU64DivBytes.includes(Buffer.from([0x00, 0x09, 0xc9, 0x9a]))); assert(!directMachOU64DivBytes.includes(Buffer.from([0x00, 0x09, 0xc9, 0x1a]))); const directMachOU64ModSource = `${outDir}/direct-macho-u64-mod.0`; const directMachOU64ModOut = `${outDir}/direct-macho-u64-mod.o`; await writeGraphFixture(directMachOU64ModSource, `export c fn main(a: u64, b: u64) -> u64 { return a % b } `); const directMachOU64ModJson = await execFileAsync(zero, ["build", "--json", "--emit", "obj", "--target", "darwin-arm64", directMachOU64ModSource, "--out", directMachOU64ModOut]); const directMachOU64ModBody = JSON.parse(directMachOU64ModJson.stdout); const directMachOU64ModBytes = await readFile(directMachOU64ModOut); assert.equal(directMachOU64ModBody.compiler, "zero-macho64"); assert.equal(directMachOU64ModBody.objectBackend.objectEmission.path, "direct-macho64-object"); assert(directMachOU64ModBytes.includes(Buffer.from([0x0a, 0x09, 0xc9, 0x9a]))); assert(directMachOU64ModBytes.includes(Buffer.from([0x40, 0xa1, 0x09, 0x9b]))); assert(!directMachOU64ModBytes.includes(Buffer.from([0x0a, 0x09, 0xc9, 0x1a]))); assert(!directMachOU64ModBytes.includes(Buffer.from([0x40, 0xa1, 0x09, 0x1b]))); const metaJsonSuccess = await execFileAsync(zero, ["check", "--json", "conformance/native/pass/meta-typed-target-type.0"]); const metaJsonSuccessBody = JSON.parse(metaJsonSuccess.stdout); assert.equal(metaJsonSuccessBody.ok, true); assert.equal(metaJsonSuccessBody.artifact, "conformance/native/pass/meta-typed-target-type.graph"); assert.equal(metaJsonSuccessBody.canonicalSource, false); assert.equal(metaJsonSuccessBody.check.lowering, "graph-native-check"); assert.equal(metaJsonSuccessBody.compileTime.deterministic, true); const stdModuleBasenameCollisionDir = `${outDir}/std-module-basename-collision`; await mkdir(stdModuleBasenameCollisionDir, { recursive: true }); const stdModuleBasenameCollisionFixture = `${stdModuleBasenameCollisionDir}/term.0`; const stdModuleBasenameCollisionGraph = await writeGraphFixture(stdModuleBasenameCollisionFixture, `pub fn main(world: World) -> Void raises { var buffer: [16]u8 = [0_u8; 16] let cursor: Maybe> = std.term.cursorUp(buffer, 1_usize) if cursor.has { check world.out.write(cursor.value) check world.out.write("local term collision ok\\n") } } `); const stdModuleBasenameCollisionCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", stdModuleBasenameCollisionGraph])).stdout); assert.equal(stdModuleBasenameCollisionCheck.ok, true); assert(stdModuleBasenameCollisionCheck.graphCompiler.semanticFacts.functions.some((fn) => fn.name === "main")); assert(stdModuleBasenameCollisionCheck.graphCompiler.semanticFacts.functions.some((fn) => fn.name === "term_cursor_up")); const stdModuleBasenameCollisionInspect = JSON.parse((await execFileAsync(zero, ["inspect", "--json", stdModuleBasenameCollisionGraph])).stdout); assert(stdModuleBasenameCollisionInspect.modules.some((module) => module.name === "term")); assert(stdModuleBasenameCollisionInspect.modules.some((module) => module.name === "std.term")); if (runnableDirectTarget) { const stdModuleBasenameCollisionRun = await execFileAsync(zero, ["run", "--out", `${outDir}/std-module-basename-collision-run`, stdModuleBasenameCollisionGraph]); assert.equal(stdModuleBasenameCollisionRun.stdout, "\x1b[1Alocal term collision ok\n"); } const collectionsUsizeMemory = await execFileAsync(zero, ["mem", "--json", "conformance/native/pass/std-collections-usize-memory.0"]); const collectionsUsizeMemoryBody = JSON.parse(collectionsUsizeMemory.stdout); assert.equal(collectionsUsizeMemoryBody.graph.artifact, "conformance/native/pass/std-collections-usize-memory.graph"); assert.equal(collectionsUsizeMemoryBody.graph.canonicalSource, false); assert.match(collectionsUsizeMemoryBody.graph.graphHash, /^graph:[0-9a-f]{16}$/); assert.equal(collectionsUsizeMemoryBody.compilerCaches.every((item) => item.sourceKind === "program-graph" && item.graphHash === collectionsUsizeMemoryBody.graph.graphHash), true); assert.equal(collectionsUsizeMemoryBody.incrementalInvalidation.sourceKind, "program-graph"); assert.equal(collectionsUsizeMemoryBody.incrementalInvalidation.changedInputs.graphArtifact, "conformance/native/pass/std-collections-usize-memory.graph"); assert.equal(collectionsUsizeMemoryBody.memoryBudgets.collectionCapacityBytes, 32); assert.equal(collectionsUsizeMemoryBody.collectionFacts.FixedStorage.capacityBytes, 32); const collectionsMutspanMemory = await execFileAsync(zero, ["mem", "--json", "conformance/native/pass/std-collections-mutspan-memory.0"]); const collectionsMutspanMemoryBody = JSON.parse(collectionsMutspanMemory.stdout); assert.equal(collectionsMutspanMemoryBody.memoryBudgets.collectionCapacityBytes, 4); assert.equal(collectionsMutspanMemoryBody.collectionFacts.FixedStorage.storageSites, 1); assert.equal(collectionsMutspanMemoryBody.collectionFacts.FixedStorage.capacityBytes, 4); const collectionsQueryMemory = await execFileAsync(zero, ["mem", "--json", "conformance/native/pass/std-collections-query-memory.0"]); const collectionsQueryMemoryBody = JSON.parse(collectionsQueryMemory.stdout); assert.equal(collectionsQueryMemoryBody.memoryBudgets.collectionCapacityBytes, 2); assert.equal(collectionsQueryMemoryBody.collectionFacts.FixedStorage.storageSites, 1); assert.equal(collectionsQueryMemoryBody.collectionFacts.FixedStorage.capacityBytes, 2); assert.equal(collectionsQueryMemoryBody.collectionFacts.FixedStorage.queryCalls, 1); const interfaceStaticUnsupportedTypeFixture = `${outDir}/interface-static-unsupported-type.0`; const interfaceStaticUnsupportedTypeBody = await writeImportFailureFixture(interfaceStaticUnsupportedTypeFixture, `interface Bad { fn value() -> u8 } pub fn main() -> Void { } `); assert.equal(interfaceStaticUnsupportedTypeBody.diagnostics[0].code, "STC001"); const interfaceMethodStaticUnsupportedTypeFixture = `${outDir}/interface-method-static-unsupported-type.0`; const interfaceMethodStaticUnsupportedTypeBody = await writeImportFailureFixture(interfaceMethodStaticUnsupportedTypeFixture, `interface Bad { fn value() -> u8 } pub fn main() -> Void { } `); assert.equal(interfaceMethodStaticUnsupportedTypeBody.diagnostics[0].code, "STC001"); const shapeMethodStaticUnsupportedTypeFixture = `${outDir}/shape-method-static-unsupported-type.0`; const shapeMethodStaticUnsupportedTypeBody = await writeImportFailureFixture(shapeMethodStaticUnsupportedTypeFixture, `type Box { value: u8, fn value(self: ref) -> u8 { return self.value } } pub fn main() -> Void { } `); assert.equal(shapeMethodStaticUnsupportedTypeBody.diagnostics[0].code, "STC001"); const methodUnknownConstraintFixtures = [ { name: "interface-method-unknown-constraint", source: `interface Bad { fn value() -> u8 } pub fn main() -> Void { } `, }, { name: "shape-method-unknown-constraint", source: `type Box { value: u8, fn value(self: ref) -> u8 { return self.value } } pub fn main() -> Void { } `, }, ]; for (const fixtureCase of methodUnknownConstraintFixtures) { const fixture = `${outDir}/${fixtureCase.name}.0`; const methodUnknownConstraintBody = await writeImportFailureFixture(fixture, fixtureCase.source); assert.equal(methodUnknownConstraintBody.diagnostics[0].code, "IFC001"); } const duplicateStaticGenericFixtures = [ { name: "function-duplicate-static-param", message: /duplicate generic parameter/, source: `fn id() -> u8 { return 1 } pub fn main() -> Void { } `, }, { name: "interface-duplicate-static-param", message: /duplicate generic parameter/, source: `interface Bad { fn value() -> u8 } pub fn main() -> Void { } `, }, { name: "shape-method-duplicate-static-param", message: /duplicate generic parameter/, source: `type Box { value: u8, fn value(self: ref) -> u8 { return self.value } } pub fn main() -> Void { } `, }, { name: "shape-method-static-shadows-shape-static", message: /shadows outer generic parameter/, source: `type Box { value: [N]u8, fn len(self: ref) -> usize { return N } } pub fn main() -> Void { } `, }, { name: "shape-method-static-self-param", message: /generic type parameter shadows Self type/, source: `type Box { value: u8, fn value(self: ref) -> usize { return Self } } pub fn main() -> Void { } `, }, ]; for (const fixtureCase of duplicateStaticGenericFixtures) { const fixture = `${outDir}/${fixtureCase.name}.0`; const duplicateStaticBody = await writeImportFailureFixture(fixture, fixtureCase.source); assert.equal(duplicateStaticBody.diagnostics[0].code, "NAM004"); assert.match(duplicateStaticBody.diagnostics[0].message, fixtureCase.message); } for (const value of ["4_", "M"]) { const fixture = `${outDir}/interface-static-constraint-${value.replace(/[^A-Za-z0-9]/g, "_")}.0`; const interfaceStaticConstraintBody = await writeImportFailureFixture(fixture, `interface First { fn first(self: ref) -> u8 } fn readFirst>(value: ref) -> u8 { return T.first(value) } pub fn main() -> Void { } `); assert.equal(interfaceStaticConstraintBody.diagnostics[0].code, "STC002"); assert.equal(interfaceStaticConstraintBody.diagnostics[0].actual, value); } const shapeMethodStaticParamFixture = `${outDir}/shape-method-static-param.0`; await writeGraphFixture(shapeMethodStaticParamFixture, `type Box { value: u8, fn tag(self: ref) -> usize { return N } fn value() -> usize { return N } } pub fn main() -> Void { let box: Box = Box { value: 1 } let receiverTag: usize = box.tag<4>() let namespaceTag: usize = Box.value<8>() } `); const shapeMethodStaticParamJson = await execFileAsync(zero, ["check", "--json", shapeMethodStaticParamFixture]); const shapeMethodStaticParamBody = JSON.parse(shapeMethodStaticParamJson.stdout); assert.equal(shapeMethodStaticParamBody.ok, true); const shapeMethodStaticParamGraph = await execFileAsync(zero, ["inspect", "--json", shapeMethodStaticParamFixture]); const shapeMethodStaticParamGraphBody = JSON.parse(shapeMethodStaticParamGraph.stdout); const shapeMethodStaticBox = shapeMethodStaticParamGraphBody.shapes.find((item) => item.name === "Box"); assert(shapeMethodStaticBox); const shapeMethodStaticTag = shapeMethodStaticBox.methods.find((item) => item.name === "tag"); assert(shapeMethodStaticTag); assert(shapeMethodStaticTag.staticParams.some((item) => item.name === "N" && item.type === "usize" && item.staticDispatch === true)); const shapeMethodStaticCanonicalFixture = `${outDir}/shape-method-static-canonical.0`; await writeGraphFixture(shapeMethodStaticCanonicalFixture, `type Box { fn take(a: [N]u8, b: [N]u8) -> usize { return N } } pub fn main() -> Void { let a: [4]u8 = [1, 2, 3, 4] let b: [0x4]u8 = [1, 2, 3, 4] let inferred: usize = Box.take(a, b) let explicit: usize = Box.take<0x4>(a, b) } `); const shapeMethodStaticCanonicalJson = await execFileAsync(zero, ["check", "--json", shapeMethodStaticCanonicalFixture]); const shapeMethodStaticCanonicalBody = JSON.parse(shapeMethodStaticCanonicalJson.stdout); assert.equal(shapeMethodStaticCanonicalBody.ok, true); const interfaceMethodStaticParamFixture = `${outDir}/interface-method-static-param.0`; await writeGraphFixture(interfaceMethodStaticParamFixture, `interface Width { fn width(self: ref) -> usize } type Bytes { value: u8, fn width(self: ref) -> usize { return N } } fn readWidth>(value: ref) -> usize { return T.width<4>(value) } pub fn main() -> Void { let bytes: Bytes = Bytes { value: 1 } let width: usize = readWidth(&bytes) } `); const interfaceMethodStaticParamJson = await execFileAsync(zero, ["check", "--json", interfaceMethodStaticParamFixture]); const interfaceMethodStaticParamBody = JSON.parse(interfaceMethodStaticParamJson.stdout); assert.equal(interfaceMethodStaticParamBody.ok, true); const interfaceMethodStaticParamGraph = await execFileAsync(zero, ["inspect", "--json", interfaceMethodStaticParamFixture]); const interfaceMethodStaticParamGraphBody = JSON.parse(interfaceMethodStaticParamGraph.stdout); const interfaceMethodStaticWidth = interfaceMethodStaticParamGraphBody.interfaces.find((item) => item.name === "Width"); assert(interfaceMethodStaticWidth); const interfaceMethodStaticWidthMethod = interfaceMethodStaticWidth.methods.find((item) => item.name === "width"); assert(interfaceMethodStaticWidthMethod); assert(interfaceMethodStaticWidthMethod.staticParams.some((item) => item.name === "N" && item.type === "usize" && item.staticDispatch === true)); const interfaceMethodStaticBytes = interfaceMethodStaticParamGraphBody.shapes.find((item) => item.name === "Bytes"); assert(interfaceMethodStaticBytes); const interfaceMethodStaticBytesWidth = interfaceMethodStaticBytes.methods.find((item) => item.name === "width"); assert(interfaceMethodStaticBytesWidth); assert(interfaceMethodStaticBytesWidth.staticParams.some((item) => item.name === "N" && item.type === "usize" && item.staticDispatch === true)); const interfaceMethodStaticRenamedParamFixture = `${outDir}/interface-method-static-renamed-param.0`; await writeGraphFixture(interfaceMethodStaticRenamedParamFixture, `interface Width { fn width(self: ref, bytes: [N]u8) -> [N]u8 } type Bytes { value: u8, fn width(self: ref, bytes: [M]u8) -> [M]u8 { return bytes } } fn readWidth>(value: ref, bytes: [4]u8) -> [4]u8 { return T.width<4>(value, bytes) } pub fn main() -> Void { let bytes: Bytes = Bytes { value: 1 } let output: [4]u8 = readWidth(&bytes, [1, 2, 3, 4]) } `); const interfaceMethodStaticRenamedParamJson = await execFileAsync(zero, ["check", "--json", interfaceMethodStaticRenamedParamFixture]); const interfaceMethodStaticRenamedParamBody = JSON.parse(interfaceMethodStaticRenamedParamJson.stdout); assert.equal(interfaceMethodStaticRenamedParamBody.ok, true); const interfaceMethodStaticRenamedParamGraph = await execFileAsync(zero, ["inspect", "--json", interfaceMethodStaticRenamedParamFixture]); const interfaceMethodStaticRenamedParamGraphBody = JSON.parse(interfaceMethodStaticRenamedParamGraph.stdout); const interfaceMethodStaticRenamedWidth = interfaceMethodStaticRenamedParamGraphBody.interfaces.find((item) => item.name === "Width"); assert(interfaceMethodStaticRenamedWidth); const interfaceMethodStaticRenamedWidthMethod = interfaceMethodStaticRenamedWidth.methods.find((item) => item.name === "width"); assert(interfaceMethodStaticRenamedWidthMethod); assert(interfaceMethodStaticRenamedWidthMethod.staticParams.some((item) => item.name === "N" && item.type === "usize" && item.staticDispatch === true)); const interfaceMethodStaticRenamedBytes = interfaceMethodStaticRenamedParamGraphBody.shapes.find((item) => item.name === "Bytes"); assert(interfaceMethodStaticRenamedBytes); const interfaceMethodStaticRenamedBytesWidth = interfaceMethodStaticRenamedBytes.methods.find((item) => item.name === "width"); assert(interfaceMethodStaticRenamedBytesWidth); assert(interfaceMethodStaticRenamedBytesWidth.staticParams.some((item) => item.name === "M" && item.type === "usize" && item.staticDispatch === true)); const staticInterfaceReturnMismatchFixture = `${outDir}/static-interface-return-mismatch.0`; const staticInterfaceReturnMismatchBody = await writeImportFailureFixture(staticInterfaceReturnMismatchFixture, `interface Sized { fn bytes(self: ref) -> [N]u8 } type Bytes { items: [N]u8, fn bytes(self: ref) -> [N]u8 { return self.items } } fn read, static N: usize>(value: ref) -> [N]u8 { return T.bytes(value) } pub fn main() -> Void { let bytes: Bytes<4> = Bytes { items: [1, 2, 3, 4] } let out: [3]u8 = read, 3>(&bytes) } `); assert.equal(staticInterfaceReturnMismatchBody.diagnostics[0].code, "IFC004"); assert.match(staticInterfaceReturnMismatchBody.diagnostics[0].expected, /\[3\]u8/); assert.match(staticInterfaceReturnMismatchBody.diagnostics[0].actual, /\[4\]u8/); const shapeMethodGenericConstraintFixture = `${outDir}/shape-method-generic-constraint.0`; const shapeMethodGenericConstraintBody = await writeImportFailureFixture(shapeMethodGenericConstraintFixture, `interface NeedsMethod { fn need(self: ref) -> u8 } type Box { value: u8, fn accept>(self: ref, item: T) -> u8 { return self.value } } type Plain { value: u8, } pub fn main() -> Void { let box: Box = Box { value: 1 } let plain: Plain = Plain { value: 2 } let out: u8 = box.accept(plain) } `); assert.equal(shapeMethodGenericConstraintBody.diagnostics[0].code, "IFC002"); const interfaceMethodGenericConstraintFixture = `${outDir}/interface-method-generic-constraint.0`; const interfaceMethodGenericConstraintBody = await writeImportFailureFixture(interfaceMethodGenericConstraintFixture, `interface NeedsMethod { fn need(self: ref) -> u8 } interface Caller { fn accept>(self: ref, item: U) -> u8 } type Box { value: u8, fn accept>(self: ref, item: U) -> u8 { return self.value } } type Plain { value: u8, } fn read>(value: ref, plain: Plain) -> u8 { return T.accept(value, plain) } pub fn main() -> Void { let box: Box = Box { value: 1 } let plain: Plain = Plain { value: 2 } let out: u8 = read(&box, plain) } `); assert.equal(interfaceMethodGenericConstraintBody.diagnostics[0].code, "IFC002"); const interfaceMethodGenericMismatchFixtures = [ { name: "interface-method-generic-constraint-mismatch", code: "IFC005", message: /constraint does not match/, source: `interface NeedsA { fn needA(self: ref) -> u8 } interface NeedsB { fn needB(self: ref) -> u8 } interface Caller { fn accept>(self: ref, item: U) -> u8 } type Box { value: u8, fn accept>(self: ref, item: U) -> u8 { return self.value } } type A { value: u8, fn needA(self: ref) -> u8 { return self.value } } fn read>(value: ref, item: A) -> u8 { return T.accept(value, item) } pub fn main() -> Void { let box: Box = Box { value: 1 } let a: A = A { value: 2 } let out: u8 = read(&box, a) } `, }, { name: "interface-method-missing-static-param", code: "IFC003", source: `interface Width { fn width(self: ref) -> usize } type Bytes { value: u8, fn width(self: ref) -> usize { return 1 } } fn readWidth>(value: ref) -> usize { return T.width<4>(value) } pub fn main() -> Void { let bytes: Bytes = Bytes { value: 1 } let width: usize = readWidth(&bytes) } `, }, { name: "interface-method-extra-static-param", code: "IFC003", source: `interface Width { fn width(self: ref) -> usize } type Bytes { value: u8, fn width(self: ref) -> usize { return N } } fn readWidth>(value: ref) -> usize { return T.width(value) } pub fn main() -> Void { let bytes: Bytes = Bytes { value: 1 } let width: usize = readWidth(&bytes) } `, }, { name: "interface-method-static-param-type-mismatch", code: "IFC005", source: `interface Width { fn width(self: ref) -> usize } type Bytes { value: u8, fn width(self: ref) -> usize { return 1 } } fn readWidth>(value: ref) -> usize { return T.width<4>(value) } pub fn main() -> Void { let bytes: Bytes = Bytes { value: 1 } let width: usize = readWidth(&bytes) } `, }, ]; for (const fixtureCase of interfaceMethodGenericMismatchFixtures) { const fixture = `${outDir}/${fixtureCase.name}.0`; const interfaceMethodGenericMismatchBody = await writeImportFailureFixture(fixture, fixtureCase.source); assert.equal(interfaceMethodGenericMismatchBody.diagnostics[0].code, fixtureCase.code); if (fixtureCase.message) assert.match(interfaceMethodGenericMismatchBody.diagnostics[0].message, fixtureCase.message); } const badTargetNameJson = await execFileAsync(zero, ["check", "--json", "--target", "not-a-target", "examples/hello.0"]).catch((error) => error); assert.notEqual(badTargetNameJson.code, 0); const badTargetNameBody = JSON.parse(badTargetNameJson.stdout); assert.equal(badTargetNameBody.diagnostics[0].code, "TAR001"); assert.match(badTargetNameBody.diagnostics[0].message, /unknown target/); assert.match(badTargetNameBody.diagnostics[0].expected, /zero targets/); assert.equal(badTargetNameBody.diagnostics[0].actual, "not-a-target"); assert.match(badTargetNameBody.diagnostics[0].help, /zero targets/); assert.equal(badTargetNameBody.diagnostics[0].fixSafety, "requires-human-review"); assert.equal(badTargetNameBody.diagnostics[0].repair.id, "manual-review"); assert.match(badTargetNameBody.diagnostics[0].related[0].message, /not-a-target/); const explainTar002 = await execFileAsync(zero, ["explain", "--json", "TAR002"]); const explainTar002Body = JSON.parse(explainTar002.stdout); assert.equal(explainTar002Body.schemaVersion, 1); assert.equal(explainTar002Body.code, "TAR002"); assert.equal(explainTar002Body.repair.id, "choose-target-with-required-capability"); const explainText = await execFileAsync(zero, ["explain", "TYP009"]); assert.match(explainText.stdout, /Mutable storage required/); const importGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/imports"]); const importGraphBody = JSON.parse(importGraph.stdout); assert.deepEqual(importGraphBody.imports, []); assert.equal(importGraphBody.sourceFiles.length, 3); assert.equal(importGraphBody.sourceMaps.length, 3); assert(importGraphBody.sourceMaps.every((item) => item.columnUnit === "utf8-byte")); assert.deepEqual(importGraphBody.targets.map((item) => item.name), ["cli"]); assert.deepEqual(importGraphBody.modules.map((item) => item.name), ["math", "types", "main"]); assert.deepEqual(importGraphBody.importEdges.map((item) => `${item.from}->${item.to}`), ["main->math", "main->types"]); assert.deepEqual(importGraphBody.importEdges.map((item) => `${item.from}->${item.to}:${item.sourceRange.path}:${item.sourceRange.start.line}:${item.sourceRange.start.column}:${item.sourceRange.end.column}`), [ "main->math:src/main.0:1:1:9", "main->types:src/main.0:3:1:10", ]); assert.deepEqual(importGraphBody.useImports.map((item) => `${item.from}->${item.to}:${item.kind}:${item.line}:${item.column}`), [ "main->math:package-local:1:1", "main->types:package-local:3:1", ]); assert.deepEqual(importGraphBody.useImports.map((item) => item.resolvedPath), [ "src/math.0", "src/types.0", ]); assert(importGraphBody.useImports.every((item) => item.sourceRange.columnUnit === "utf8-byte")); assert(importGraphBody.functions.some((item) => item.name === "add_one" && item.returnType === "i32")); assert(importGraphBody.functions.some((item) => item.name === "main" && item.returnType === "Void" && item.effects.includes("world"))); const whitespaceUsePackage = `${outDir}/use-whitespace-package`; await mkdir(`${whitespaceUsePackage}/src`, { recursive: true }); await writeZeroToml(whitespaceUsePackage, { package: { name: "use-whitespace-package", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, deps: {}, }); await mkdir(`${whitespaceUsePackage}/src/math`, { recursive: true }); await writeFile(`${whitespaceUsePackage}/src/math.0`, 'fn add_one(value: i32) -> i32 {\n return value + 1\n}\n'); await writeFile(`${whitespaceUsePackage}/src/math/util.0`, 'fn add_two(value: i32) -> i32 {\n return value + 2\n}\n'); await writeFile(`${whitespaceUsePackage}/src/types.0`, 'type Point {\n value: i32,\n}\n'); await writeFile(`${whitespaceUsePackage}/src/main.0`, 'use math\nuse math . util\nuse types as model\n\npub fn main(world: World) -> Void raises {\n let point: Point = Point { value: add_two(40) }\n if point.value == add_one(41) {\n check world.out.write("whitespace imports pass\\n")\n }\n}\n'); await importPackageGraph(whitespaceUsePackage); const whitespaceUseCheck = await execFileAsync(zero, ["check", "--json", whitespaceUsePackage]); assert.equal(JSON.parse(whitespaceUseCheck.stdout).ok, true); const whitespaceUseGraph = await execFileAsync(zero, ["inspect", "--json", whitespaceUsePackage]); const whitespaceUseGraphBody = JSON.parse(whitespaceUseGraph.stdout); assert.deepEqual(whitespaceUseGraphBody.useImports.map((item) => `${item.from}->${item.to}:${item.kind}:${item.alias ?? "null"}:${item.sourceRange.end.column}`), [ "main->math:package-local:null:9", "main->math.util:package-local:null:14", "main->types:package-local:model:10", ]); assert.deepEqual(whitespaceUseGraphBody.importEdges.map((item) => `${item.from}->${item.to}`), ["main->math", "main->math.util", "main->types"]); const packageUseGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/package"]); const packageUseGraphBody = JSON.parse(packageUseGraph.stdout); assert.deepEqual(packageUseGraphBody.useImports.map((item) => `${item.from}->${item.to}:${item.kind}:${item.resolvedPath ?? "null"}`), [ "main->std.codec:stdlib:null", "main->std.parse:stdlib:null", "main->std.time:stdlib:null", "main->types:package-local:src/types.0", ]); const resourceGraph = await execFileAsync(zero, ["inspect", "--json", "examples/resource-cli"]); const resourceGraphBody = JSON.parse(resourceGraph.stdout); assert(resourceGraphBody.targets.some((item) => item.name === "cli" && item.kind === "exe")); assert.deepEqual(resourceGraphBody.importEdges.map((item) => `${item.from}->${item.to}`), ["main->config", "main->payload"]); assert(resourceGraphBody.requiresCapabilities.includes("fs")); assert(resourceGraphBody.functions.some((item) => item.name === "outputDir" && item.effects.includes("env"))); const resourceMainFunction = resourceGraphBody.functions.find((item) => item.name === "main"); assert(resourceMainFunction.effects.includes("fs")); assert.equal(resourceMainFunction.allocationBehavior, "no heap allocation"); assert.equal(resourceMainFunction.ownership.params[0].type, "World"); const memoryGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "linux-musl-x64", "examples/memory-package"]); const memoryGraphBody = JSON.parse(memoryGraph.stdout); assert.deepEqual(memoryGraphBody.importEdges.map((item) => `${item.from}->${item.to}`), ["main->buffer", "main->checksum"]); assert(memoryGraphBody.requiresCapabilities.includes("memory")); assert(!memoryGraphBody.requiresCapabilities.includes("fs")); assert.equal(memoryGraphBody.targetSupport.fsAvailable, true); assert.equal(memoryGraphBody.targetSupport.requiredCapabilitySupport.status, "supported"); assert.equal(memoryGraphBody.functions.filter((item) => item.public).length, 5); assert(memoryGraphBody.stdlibHelpers.some((helper) => helper.name === "std.mem.copy" && helper.targetSupport === "target-neutral")); assert(memoryGraphBody.stdlibHelpers.some((helper) => helper.name === "std.fs.createOrRaise" && helper.targetSupport === "host")); const memCopyHelper = memoryGraphBody.stdlibHelpers.find((helper) => helper.name === "std.mem.copy"); assert.equal(memCopyHelper.module, "std.mem"); assert(memCopyHelper.effects.includes("memory")); assert.equal(memCopyHelper.errorBehavior, "infallible"); assert.match(memCopyHelper.ownershipNotes, /caller-owned storage/); assert.equal(memCopyHelper.example, "examples/memory-primitives.0"); assert.equal(memCopyHelper.apiStability, "bootstrap-stable"); const lexerTokens = await execFileAsync(zero, ["tokens", "--json", "conformance/lexer/compiler-smoke.0"]); const lexerTokensBody = JSON.parse(lexerTokens.stdout); assert.equal(lexerTokensBody.schemaVersion, 1); assert.equal(lexerTokensBody.syntax, "canonical"); assert.deepEqual(lexerTokensBody.tokens.slice(0, 4).map((token) => `${token.kind}:${token.text}`), [ "word:use", "word:std", "symbol:.", "word:mem", ]); assert.deepEqual(lexerTokensBody.tokens.filter((token) => token.kind === "number").map((token) => token.text), ["123", "0xff", "0b101", "42_u8"]); assert.deepEqual(lexerTokensBody.tokens.filter((token) => token.kind === "string" || token.kind === "char").map((token) => `${token.kind}:${token.text}`), [ 'string:"hi"', "char:'x'", ]); assert.equal(lexerTokensBody.tokens[0].line, 1); assert.equal(lexerTokensBody.tokens[0].column, 1); assert.equal(lexerTokensBody.tokens[0].offset, 0); assert.equal(lexerTokensBody.tokens[0].length, 3); assert.equal(lexerTokensBody.tokens[5].offset, 12); assert.equal(lexerTokensBody.tokens[5].length, 1); assert.equal(lexerTokensBody.tokens[8].kind, "word"); assert.equal(lexerTokensBody.tokens[8].text, "main"); assert.equal(lexerTokensBody.tokens[8].line, 3); assert.equal(lexerTokensBody.tokens[8].column, 8); assert.equal(lexerTokensBody.tokens.at(-1).kind, "eof"); assert.equal(lexerTokensBody.tokens.at(-1).length, 0); const parseTree = await execFileAsync(zero, ["parse", "--json", "conformance/format/functions-blocks.0"]); const parseTreeBody = JSON.parse(parseTree.stdout); assert.equal(parseTreeBody.schemaVersion, 1); assert.equal(parseTreeBody.root.kind, "module"); assert.equal(parseTreeBody.root.shapeCount, 0); assert.equal(parseTreeBody.root.enumCount, 0); assert.equal(parseTreeBody.root.choiceCount, 0); assert.equal(parseTreeBody.root.functionCount, 2); assert.equal(parseTreeBody.functions[0].name, "helper"); assert.equal(parseTreeBody.functions[0].paramCount, 1); assert.deepEqual(parseTreeBody.functions[0].bodyKinds, ["if"]); assert.equal(parseTreeBody.functions[1].name, "main"); assert.equal(parseTreeBody.functions[1].paramCount, 0); assert.deepEqual(parseTreeBody.functions[1].bodyKinds, ["let", "while"]); const constGraph = await execFileAsync(zero, ["inspect", "--json", "examples/const-arithmetic.0"]); const constGraphBody = JSON.parse(constGraph.stdout); assert(constGraphBody.consts.some((item) => item.name === "answer" && item.type === "i32")); const genericPairGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/generic-shape-multi.0"]); const genericPairGraphBody = JSON.parse(genericPairGraph.stdout); assert(genericPairGraphBody.functions.some((item) => item.name === "makePair" && item.generic === true && item.returnType === "Pair")); assert(genericPairGraphBody.shapes.some((item) => item.name === "Pair" && item.generic === true && item.typeParams.join(",") === "T,U")); const staticValueGraph = await execFileAsync(zero, ["inspect", "--json", "examples/static-value-params.0"]); const staticValueGraphBody = JSON.parse(staticValueGraph.stdout); const fixedVecShape = staticValueGraphBody.shapes.find((item) => item.name === "FixedVec"); assert(fixedVecShape); assert(fixedVecShape.staticParams.some((item) => item.name === "N" && item.type === "usize" && item.staticDispatch === true)); assert(staticValueGraphBody.functions.some((item) => item.name === "first" && item.staticParams.some((param) => param.name === "N"))); const fixedVecGraph = await execFileAsync(zero, ["inspect", "--json", "examples/fixed-vec.0"]); const fixedVecGraphBody = JSON.parse(fixedVecGraph.stdout); const fixedVecMethodsShape = fixedVecGraphBody.shapes.find((item) => item.name === "FixedVec"); assert(fixedVecMethodsShape); const pushMethod = fixedVecMethodsShape.methods.find((item) => item.name === "push"); assert(pushMethod); assert.equal(pushMethod.inheritedShapeParams, true); assert.deepEqual(pushMethod.shapeTypeParams, ["T", "N"]); assert(pushMethod.shapeStaticParams.some((item) => item.name === "N" && item.staticDispatch === true)); const aliasGraph = await execFileAsync(zero, ["inspect", "--json", "examples/type-alias.0"]); const aliasGraphBody = JSON.parse(aliasGraph.stdout); assert(aliasGraphBody.aliases.some((item) => item.name === "BytePair" && item.target === "Pair")); const staticMethodGraph = await execFileAsync(zero, ["inspect", "--json", "examples/static-method.0"]); const staticMethodGraphBody = JSON.parse(staticMethodGraph.stdout); const counterShape = staticMethodGraphBody.shapes.find((item) => item.name === "Counter"); assert(counterShape); assert(counterShape.methods.some((item) => item.name === "add" && item.staticDispatch === true && item.returnType === "i32")); const staticInterfaceGraph = await execFileAsync(zero, ["inspect", "--json", "examples/static-interface.0"]); const staticInterfaceGraphBody = JSON.parse(staticInterfaceGraph.stdout); assert(staticInterfaceGraphBody.interfaces.some((item) => item.name === "Readable" && item.staticOnly === true)); assert(staticInterfaceGraphBody.functions.some((item) => item.name === "readValue" && item.constraints.some((constraint) => constraint.interface === "Readable" && constraint.staticDispatch === true))); const callResolutionGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/call-resolution-inspection.0"]); const callResolutionGraphBody = JSON.parse(callResolutionGraph.stdout); const callFacts = callResolutionGraphBody.callResolution; assert.equal(callFacts.schemaVersion, 1); for (const kind of ["function", "stdlib", "receiver", "shape_namespace", "constrained_interface", "concrete_constrained_shape", "choice_constructor"]) { assert(callFacts.supportedKinds.includes(kind)); assert(callFacts.calls.some((item) => item.kind === kind), `missing call-resolution fact for ${kind}`); } assert(callFacts.calls.some((item) => item.kind === "function" && item.calleeName === "add" && item.returnType === "i32" && item.expectedArgCount === 2)); assert(callFacts.calls.some((item) => item.kind === "function" && item.calleeName === "id" && item.bindings.some((binding) => binding.name === "T" && binding.type === "i32"))); assert(callFacts.calls.some((item) => item.kind === "function" && item.calleeName === "id" && item.owner === "wrap" && item.instantiationDepth === 1 && item.instantiatedBy === "main" && item.returnType === "i32")); assert(callFacts.calls.some((item) => item.kind === "stdlib" && item.calleeName === "std.mem.len" && item.returnType === "usize" && item.args.some((arg) => arg.actualType === "String"))); assert(callFacts.calls.some((item) => item.kind === "choice_constructor" && item.calleeName === "Event.key" && item.choice === "Event" && item.choiceCase === "key")); assert(callFacts.calls.some((item) => item.kind === "shape_namespace" && item.calleeName === "read" && item.shape === "Counter")); assert(callFacts.calls.some((item) => item.kind === "receiver" && item.calleeName === "bump" && item.shape === "Counter" && item.paramOffset === 1)); assert(callFacts.calls.some((item) => item.kind === "constrained_interface" && item.calleeName === "read" && item.interface === "Readable" && item.owner === "readValue")); assert(callFacts.calls.some((item) => item.kind === "concrete_constrained_shape" && item.calleeName === "read" && item.shape === "Counter" && item.instantiatedBy === "main")); assert(callFacts.calls.some((item) => item.calleeName === "add" && item.path === "call-resolution-inspection.0")); assert(callFacts.calls.some((item) => item.kind === "function" && item.calleeName === "defaultCount" && item.owner === "Counter.value" && item.returnType === "i32")); assert(callFacts.calls.some((item) => item.kind === "function" && item.calleeName === "risky" && item.fallible === true && item.errors.includes("BadInput"))); assert(callFacts.calls.some((item) => item.kind === "receiver" && item.calleeName === "checkedRead" && item.fallible === true && item.errors.includes("EmptyCounter"))); const callResolutionMemGetGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/native/pass/checked-bounds-get.0"]); const callResolutionMemGetFacts = JSON.parse(callResolutionMemGetGraph.stdout).callResolution; assert(callResolutionMemGetFacts.calls.some((item) => item.kind === "stdlib" && item.calleeName === "std.mem.get" && item.returnType === "Maybe" && item.args.some((arg) => arg.paramIndex === 0 && arg.actualType === "[3]u8"))); const callResolutionGenericShapeGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/generic-shape-methods.0"]); const callResolutionGenericShapeFacts = JSON.parse(callResolutionGenericShapeGraph.stdout).callResolution; assert(callResolutionGenericShapeFacts.calls.some((item) => item.kind === "stdlib" && item.calleeName === "std.mem.get" && item.owner === "FixedVec.get" && item.instantiationDepth === 1 && item.instantiatedBy === "main" && item.returnType === "Maybe" && item.args.some((arg) => arg.paramIndex === 0 && arg.actualType === "[4]u8") )); const callResolutionFsReadGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/native/pass/std-fs-resource.0"]); const callResolutionFsReadFacts = JSON.parse(callResolutionFsReadGraph.stdout).callResolution; assert(callResolutionFsReadFacts.calls.some((item) => item.kind === "stdlib" && item.calleeName === "std.fs.read" && item.returnType === "Maybe" && item.args.some((arg) => arg.paramIndex === 0 && arg.expectedType === "mutref" && arg.actualType === "mutref"))); const callResolutionPackageGraph = await execFileAsync(zero, ["inspect", "--json", "examples/systems-package"]); const callResolutionPackageFacts = JSON.parse(callResolutionPackageGraph.stdout).callResolution; assert(callResolutionPackageFacts.calls.some((item) => item.calleeName === "cleanup" && item.path === "src/main.0" && item.line === 18)); const callResolutionEdgeGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/call-resolution-edge-cases.0"]); const callResolutionEdgeFacts = JSON.parse(callResolutionEdgeGraph.stdout).callResolution; assert(callResolutionEdgeFacts.calls.some((item) => item.kind === "function" && item.calleeName === "add" && item.owner === "constTotal" && item.returnType === "i32")); assert(callResolutionEdgeFacts.calls.some((item) => item.kind === "stdlib" && item.calleeName === "std.mem.len" && item.owner === "main" && item.args.some((arg) => arg.paramIndex === 0 && arg.actualType === "String"))); const programGraphBody = JSON.parse((await execFileAsync(zero, ["inspect", "--json", "examples/hello.0"])).stdout).programGraph; const programGraphBodyAgain = JSON.parse((await execFileAsync(zero, ["inspect", "--json", "examples/hello.0"])).stdout).programGraph; const programGraphDump = (await execFileAsync(zero, ["dump", "examples/hello.0"])).stdout; const programGraphDumpAgain = (await execFileAsync(zero, ["dump", "examples/hello.0"])).stdout; const programGraphDumpJson = JSON.parse((await execFileAsync(zero, ["dump", "--json", "examples/hello.0"])).stdout); const programGraphDumpPath = `${outDir}/hello.program-graph`; const programGraphDumpJsonPath = `${outDir}/hello.dump-json.program-graph`; const programGraphCanonicalPath = `${outDir}/hello.canonical.program-graph`; const programGraphViewPath = `${outDir}/hello.graph-view.0`; const programGraphArtifactRoundtripPath = `${outDir}/hello.roundtrip.program-graph`; const programGraphSourceFixturePath = "conformance/program-graph/hello.0"; const programGraphSourceFixturePackage = "conformance/program-graph"; const programGraphSourceFixtureStorePath = "conformance/program-graph/zero.graph"; const programGraphSourceFixtureRunPath = `${outDir}/program-graph-fixture-run`; const programGraphSourceFreePackage = `${outDir}/program-graph-source-free`; const programGraphSourceFreeBuildPath = `${outDir}/program-graph-source-free-build`; const programGraphSourceFreeRunPath = `${outDir}/program-graph-source-free-run`; const programGraphSourceFreeStdStrPackage = `${outDir}/program-graph-source-free-std-str`; const programGraphCrmApiBuildPath = `${outDir}/program-graph-crm-api-build`; const programGraphAuthoringPackage = `${outDir}/program-graph-authoring`; const programGraphAuthoringRunPath = `${outDir}/program-graph-authoring-run`; const programGraphAuthoringRunAfterHumanEditPath = `${outDir}/program-graph-authoring-run-human-edit`; const programGraphBuilderOpsPackage = `${outDir}/program-graph-builder-ops`; const programGraphBuilderOpsRunPath = `${outDir}/program-graph-builder-ops-run`; const programGraphLoopTestPackage = `${outDir}/program-graph-loop-test`; const programGraphArrayLengthPackage = `${outDir}/program-graph-array-length-mismatch`; const programGraphBlockBodyPackage = `${outDir}/program-graph-block-body`; const programGraphBlockBodyRunPath = `${outDir}/program-graph-block-body-run`; const programGraphAuthoringCliPackage = `${outDir}/program-graph-authoring-cli`; const programGraphAuthoringCliGraphBuildPath = `${outDir}/program-graph-authoring-cli-graph-build`; const programGraphAuthoringCliBuildPath = `${outDir}/program-graph-authoring-cli-build`; const programGraphAuthoringCliRunPath = `${outDir}/program-graph-authoring-cli-run`; const programGraphAuthoringCliRunAfterHumanEditPath = `${outDir}/program-graph-authoring-cli-run-human-edit`; const programGraphSourceFreeCImportPackage = `${outDir}/program-graph-source-free-c-import`; const programGraphSourceFreeCImportRunPath = `${outDir}/program-graph-source-free-c-import-run`; const programGraphSourceFreeCImportCwdPackage = `${outDir}/program-graph-source-free-c-import-cwd`; const programGraphSourceFreeCImportCwdBuildPath = `${outDir}/program-graph-source-free-c-import-cwd-build`; const programGraphIdentityMismatchPackage = `${outDir}/program-graph-identity-mismatch`; const programGraphMissingPackageNamePackage = `${outDir}/program-graph-missing-package-name`; const programGraphBadProjectionPackage = `${outDir}/program-graph-bad-projection`; const programGraphSourceFixtureDriftPackage = `${outDir}/program-graph-fixture-drift`; const programGraphMissingStorePackage = `${outDir}/program-graph-missing-store`; const programGraphInvalidStorePackage = `${outDir}/program-graph-invalid-store`; const programGraphTargetWebbitsPackage = `${outDir}/program-graph-target-webbits`; const programGraphTargetIncompatiblePackage = `${outDir}/program-graph-target-incompatible`; const programGraphTargetCapabilityPackage = `${outDir}/program-graph-target-capability`; const programGraphRichPath = `${outDir}/open-ended-slices.program-graph`; const programGraphRichViewPath = `${outDir}/open-ended-slices.graph-view.0`; const programGraphCharPath = `${outDir}/float-char-casts.program-graph`; const programGraphCharViewPath = `${outDir}/float-char-casts.graph-view.0`; await rm(programGraphDumpPath, { force: true }); await rm(programGraphDumpJsonPath, { force: true }); await rm(programGraphCanonicalPath, { force: true }); await rm(programGraphViewPath, { force: true }); await rm(programGraphArtifactRoundtripPath, { force: true }); await rm(programGraphSourceFixtureRunPath, { force: true }); await rm(programGraphSourceFreePackage, { recursive: true, force: true }); await rm(programGraphSourceFreeBuildPath, { force: true }); await rm(programGraphSourceFreeRunPath, { force: true }); await rm(programGraphSourceFreeStdStrPackage, { recursive: true, force: true }); await rm(programGraphCrmApiBuildPath, { force: true }); await rm(programGraphAuthoringPackage, { recursive: true, force: true }); await rm(programGraphAuthoringRunPath, { force: true }); await rm(programGraphAuthoringRunAfterHumanEditPath, { force: true }); await rm(programGraphBuilderOpsPackage, { recursive: true, force: true }); await rm(programGraphBuilderOpsRunPath, { force: true }); await rm(programGraphLoopTestPackage, { recursive: true, force: true }); await rm(programGraphArrayLengthPackage, { recursive: true, force: true }); await rm(programGraphBlockBodyPackage, { recursive: true, force: true }); await rm(programGraphBlockBodyRunPath, { force: true }); await rm(programGraphAuthoringCliPackage, { recursive: true, force: true }); await rm(programGraphAuthoringCliGraphBuildPath, { force: true }); await rm(programGraphAuthoringCliBuildPath, { force: true }); await rm(programGraphAuthoringCliRunPath, { force: true }); await rm(programGraphAuthoringCliRunAfterHumanEditPath, { force: true }); await rm(programGraphSourceFreeCImportPackage, { recursive: true, force: true }); await rm(programGraphSourceFreeCImportRunPath, { force: true }); await rm(programGraphSourceFreeCImportCwdPackage, { recursive: true, force: true }); await rm(programGraphSourceFreeCImportCwdBuildPath, { force: true }); await rm(programGraphIdentityMismatchPackage, { recursive: true, force: true }); await rm(programGraphMissingPackageNamePackage, { recursive: true, force: true }); await rm(programGraphBadProjectionPackage, { recursive: true, force: true }); await rm(programGraphSourceFixtureDriftPackage, { recursive: true, force: true }); await rm(programGraphMissingStorePackage, { recursive: true, force: true }); await rm(programGraphInvalidStorePackage, { recursive: true, force: true }); await rm(programGraphTargetWebbitsPackage, { recursive: true, force: true }); await rm(programGraphTargetIncompatiblePackage, { recursive: true, force: true }); await rm(programGraphTargetCapabilityPackage, { recursive: true, force: true }); await rm(programGraphRichPath, { force: true }); await rm(programGraphRichViewPath, { force: true }); await rm(programGraphCharPath, { force: true }); await rm(programGraphCharViewPath, { force: true }); const programGraphDumpOut = await execFileAsync(zero, ["dump", "--out", programGraphDumpPath, "examples/hello.0"]); const programGraphDumpOutJson = JSON.parse((await execFileAsync(zero, ["dump", "--json", "--out", programGraphDumpJsonPath, "examples/hello.0"])).stdout); const programGraphDumpFile = await readFile(programGraphDumpPath, "utf8"); const programGraphDumpJsonFile = await readFile(programGraphDumpJsonPath, "utf8"); const programGraphValidate = await execFileAsync(zero, ["validate", programGraphDumpPath]); const programGraphDumpJsonValidate = await execFileAsync(zero, ["validate", programGraphDumpJsonPath]); const programGraphValidateJson = JSON.parse((await execFileAsync(zero, ["validate", "--json", "--out", programGraphCanonicalPath, programGraphDumpPath])).stdout); const programGraphCanonicalFile = await readFile(programGraphCanonicalPath, "utf8"); const programGraphView = (await execFileAsync(zero, ["view", programGraphDumpPath])).stdout; const programGraphViewAgain = (await execFileAsync(zero, ["view", programGraphDumpPath])).stdout; const programGraphViewJson = JSON.parse((await execFileAsync(zero, ["view", "--json", programGraphDumpPath])).stdout); const programGraphViewOut = await execFileAsync(zero, ["view", "--out", programGraphViewPath, programGraphDumpPath]); const programGraphViewFile = await readFile(programGraphViewPath, "utf8"); const programGraphViewOutJson = JSON.parse((await execFileAsync(zero, ["view", "--json", "--out", programGraphViewPath, programGraphDumpPath])).stdout); const programGraphRoundtrip = await execFileAsync(zero, ["roundtrip", "examples/hello.0"]); const programGraphRoundtripJson = JSON.parse((await execFileAsync(zero, ["roundtrip", "--json", "examples/hello.0"])).stdout); const programGraphArtifactRoundtrip = await execFileAsync(zero, ["roundtrip", programGraphDumpPath]); const programGraphArtifactRoundtripJson = JSON.parse((await execFileAsync(zero, ["roundtrip", "--json", "--out", programGraphArtifactRoundtripPath, programGraphDumpPath])).stdout); const programGraphSourceFixtureText = await readFile(programGraphSourceFixturePath, "utf8"); const programGraphSourceFixtureStoreBytes = await readFile(programGraphSourceFixtureStorePath); const programGraphSourceFixturePackageCheckJson = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphSourceFixturePackage])).stdout); const programGraphSourceFixturePackageStatusJson = JSON.parse((await execFileAsync(zero, ["status", "--json", programGraphSourceFixturePackage])).stdout); const programGraphSourceFixturePackageRun = await execFileAsync(zero, ["run", "--out", programGraphSourceFixtureRunPath, programGraphSourceFixturePackage]); await mkdir(programGraphSourceFreePackage, { recursive: true }); await writeFile(`${programGraphSourceFreePackage}/zero.toml`, await readFile(`${programGraphSourceFixturePackage}/zero.toml`, "utf8")); await writeFile(`${programGraphSourceFreePackage}/zero.graph`, programGraphSourceFixtureStoreBytes); const programGraphSourceFreeCheckJson = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphSourceFreePackage])).stdout); const programGraphSourceFreeSizeJson = JSON.parse((await execFileAsync(zero, ["size", "--json", "--target", "linux-musl-x64", programGraphSourceFreePackage])).stdout); const programGraphSourceFreeBuildJson = JSON.parse((await execFileAsync(zero, ["build", "--json", "--target", "linux-musl-x64", "--out", programGraphSourceFreeBuildPath, programGraphSourceFreePackage])).stdout); const programGraphSourceFreeMappedMirCache = programGraphSourceFreeBuildJson.graphBuild?.mappedFinalMir; const programGraphSourceFreeMappedMirCachePath = programGraphSourceFreeMappedMirCache?.path ?? ""; const programGraphSourceFreeRun = await execFileAsync(zero, ["run", "--out", programGraphSourceFreeRunPath, programGraphSourceFreePackage]); const programGraphSourceFreeTestJson = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphSourceFreePackage])).stdout); const programGraphSourceFreeMemJson = JSON.parse((await execFileAsync(zero, ["mem", "--json", programGraphSourceFreePackage])).stdout); const programGraphSourceFreeVerify = await execFileAsync(zero, ["verify-projection", "--json", programGraphSourceFreePackage]).catch((error) => error); const programGraphSourceFreeExport = JSON.parse((await execFileAsync(zero, ["export", "--json", programGraphSourceFreePackage])).stdout); const programGraphSourceFreeVerifyAfter = JSON.parse((await execFileAsync(zero, ["verify-projection", "--json", programGraphSourceFreePackage])).stdout); await mkdir(programGraphSourceFreeStdStrPackage, { recursive: true }); await writeZeroToml(programGraphSourceFreeStdStrPackage, { package: { name: "program-graph-source-free-std-str", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "main.0" } }, }); await writeFile(`${programGraphSourceFreeStdStrPackage}/main.0`, await readFile("examples/std-str.0", "utf8")); const programGraphSourceFreeStdStrSync = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphSourceFreeStdStrPackage])).stdout); await rm(`${programGraphSourceFreeStdStrPackage}/main.0`, { force: true }); const programGraphSourceFreeStdStrCheckJson = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphSourceFreeStdStrPackage])).stdout); const programGraphCrmApiCheckJson = JSON.parse((await execFileAsync(zero, ["check", "--json", "examples/crm-api"])).stdout); const programGraphCrmApiStatusJson = JSON.parse((await execFileAsync(zero, ["status", "--json", "examples/crm-api"])).stdout); const programGraphCrmApiBuildJson = JSON.parse((await execFileAsync(zero, ["build", "--json", "--out", programGraphCrmApiBuildPath, "examples/crm-api"])).stdout); const programGraphCrmApiHealth = await execFileAsync(programGraphCrmApiBuildPath, ["GET /health\n\n"]); const programGraphCrmApiAccounts = await execFileAsync(programGraphCrmApiBuildPath, ["GET /crm/accounts?tenant=demo\n\n"]); const programGraphCrmApiDealUpdate = await execFileAsync(programGraphCrmApiBuildPath, ["POST /crm/deals/42/update\ncontent-type: application/json\n\n{\"stage\":\"won\"}"]); const programGraphCrmApiMissing = await execFileAsync(programGraphCrmApiBuildPath, ["GET /missing\n\n"]); const programGraphAuthoringInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringProjectionExistsAfterInit = await fileExists(`${programGraphAuthoringPackage}/src/main.0`); const programGraphAuthoringPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addMain", "--op", "addFunction name=\"add\" ret=\"i32\"", "--op", "addParam fn=\"add\" name=\"left\" type=\"i32\"", "--op", "addParam fn=\"add\" name=\"right\" type=\"i32\"", "--op", "addReturnBinary fn=\"add\" name=\"+\" left=\"left\" right=\"right\" type=\"i32\"", "--op", "addCheckWrite fn=\"main\" text=\"graph authoring ok\\n\"", "--op", "addTest name=\"addition works\" call=\"add\" arg0=\"40\" arg1=\"2\" expect=\"42\" type=\"i32\"", ], { cwd: programGraphAuthoringPackage })).stdout); const programGraphAuthoringProjectionExistsAfterPatch = await fileExists(`${programGraphAuthoringPackage}/src/main.0`); const programGraphAuthoringStatusMissing = JSON.parse((await execFileAsync(zero, ["status", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringVerifyMissing = await execFileAsync(zero, ["verify-projection", "--json", programGraphAuthoringPackage]).catch((error) => error); const programGraphAuthoringCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringRun = await execFileAsync(zero, ["run", "--out", programGraphAuthoringRunPath, programGraphAuthoringPackage]); const programGraphAuthoringTest = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringExport = JSON.parse((await execFileAsync(zero, ["export", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringProjectionText = await readFile(`${programGraphAuthoringPackage}/src/main.0`, "utf8"); const programGraphAuthoringVerifyAfter = JSON.parse((await execFileAsync(zero, ["verify-projection", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringCheckAfter = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringEditedText = programGraphAuthoringProjectionText.replace("graph authoring ok", "human edit ok"); await writeFile(`${programGraphAuthoringPackage}/src/main.0`, programGraphAuthoringEditedText); const programGraphAuthoringStatusAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["status", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringImport = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringCheckAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphAuthoringPackage])).stdout); const programGraphAuthoringRunAfterHumanEdit = await execFileAsync(zero, ["run", "--out", programGraphAuthoringRunAfterHumanEditPath, programGraphAuthoringPackage]); const programGraphBuilderOpsInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphBuilderOpsPackage])).stdout); const programGraphBuilderOpsPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addMain", "--op", "addLetLiteral fn=\"main\" name=\"message\" type=\"String\" value=\"graph value write ok\\n\"", "--op", "addCheckWriteValue fn=\"main\" value=\"message\" type=\"String\"", "--op", "addFunction name=\"add_twice\" ret=\"u32\"", "--op", "addParam fn=\"add_twice\" name=\"x\" type=\"u32\"", "--op", "addParam fn=\"add_twice\" name=\"y\" type=\"u32\"", "--op", "addLetBinary fn=\"add_twice\" name=\"first\" type=\"u32\" operator=\"+\" left=\"x\" right=\"y\"", "--op", "addLetBinary fn=\"add_twice\" name=\"total\" type=\"u32\" operator=\"+\" left=\"first\" right=\"y\"", "--op", "addReturnValue fn=\"add_twice\" value=\"total\" type=\"u32\"", "--op", "addTest name=\"add twice\" call=\"add_twice\" arg0=\"3\" arg1=\"2\" expect=\"7\" type=\"u32\"", ], { cwd: programGraphBuilderOpsPackage })).stdout); const programGraphBuilderOpsProjectionExistsAfterPatch = await fileExists(`${programGraphBuilderOpsPackage}/src/main.0`); const programGraphBuilderOpsQuery = JSON.parse((await execFileAsync(zero, ["query", "--json", programGraphBuilderOpsPackage])).stdout); const programGraphBuilderOpsView = (await execFileAsync(zero, ["view", programGraphBuilderOpsPackage])).stdout; const programGraphBuilderOpsCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphBuilderOpsPackage])).stdout); const programGraphBuilderOpsTest = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphBuilderOpsPackage])).stdout); const programGraphBuilderOpsRun = await execFileAsync(zero, ["run", "--out", programGraphBuilderOpsRunPath, programGraphBuilderOpsPackage]); const programGraphBuilderOpsSync = JSON.parse((await execFileAsync(zero, ["export", "--json", programGraphBuilderOpsPackage])).stdout); const programGraphBuilderOpsProjectionText = await readFile(`${programGraphBuilderOpsPackage}/src/main.0`, "utf8"); const programGraphLoopTestInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphLoopTestPackage])).stdout); const programGraphLoopTestPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addMain", "--op", "addFunction name=\"count_to\" ret=\"u32\"", "--op", "addParam fn=\"count_to\" name=\"n\" type=\"u32\"", "--op", "addParam fn=\"count_to\" name=\"start\" type=\"u32\"", "--op", "addReturnBinary fn=\"count_to\" name=\"+\" left=\"n\" right=\"start\" type=\"u32\"", ], { cwd: programGraphLoopTestPackage })).stdout); const programGraphLoopTestBodyQuery = JSON.parse((await execFileAsync(zero, ["query", "--json", programGraphLoopTestPackage])).stdout); const programGraphLoopTestBodyPatchText = [ "zero-program-graph-patch v1", `expect graphHash "${programGraphLoopTestBodyQuery.graphHash}"`, "replaceFunctionBody count_to", " var i u32 = start", " while i < n", " i = i + 1", " return i", "end", "", ].join("\n"); const programGraphLoopTestBodyPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", programGraphLoopTestPackage, "--patch-text", programGraphLoopTestBodyPatchText])).stdout); const programGraphLoopTestAddTest = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addTest name=\"graph while assignment\" call=\"count_to\" arg0=\"4\" arg1=\"0\" expect=\"4\" type=\"u32\"", ], { cwd: programGraphLoopTestPackage })).stdout); const programGraphLoopTestCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphLoopTestPackage])).stdout); const programGraphLoopTestRun = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphLoopTestPackage])).stdout); const programGraphLoopTestView = (await execFileAsync(zero, ["view", programGraphLoopTestPackage])).stdout; const programGraphArrayLengthInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphArrayLengthPackage])).stdout); const programGraphArrayLengthMainPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", "--op", "addMain", programGraphArrayLengthPackage])).stdout); const programGraphArrayLengthRepeatBodyPath = `${outDir}/program-graph-array-length-repeat-body.0`; await writeFile(programGraphArrayLengthRepeatBodyPath, 'var b: [64]u8 = [0_u8; 32]\ncheck world.out.write("unreachable\\n")\n'); const programGraphArrayLengthRepeatPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", "--replace-fn", "main", "--body-file", programGraphArrayLengthRepeatBodyPath, programGraphArrayLengthPackage]).catch((error) => error)).stdout); const programGraphArrayLengthListBodyPath = `${outDir}/program-graph-array-length-list-body.0`; await writeFile(programGraphArrayLengthListBodyPath, 'var b: [4]u8 = [1, 2]\ncheck world.out.write("unreachable\\n")\n'); const programGraphArrayLengthListPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", "--replace-fn", "main", "--body-file", programGraphArrayLengthListBodyPath, programGraphArrayLengthPackage]).catch((error) => error)).stdout); const programGraphArrayLengthMatchingBodyPath = `${outDir}/program-graph-array-length-matching-body.0`; await writeFile(programGraphArrayLengthMatchingBodyPath, 'var b: [4]u8 = [0_u8; 4]\nb[0] = 1\ncheck world.out.write("lengths agree\\n")\n'); const programGraphArrayLengthMatchingPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", "--replace-fn", "main", "--body-file", programGraphArrayLengthMatchingBodyPath, programGraphArrayLengthPackage])).stdout); const programGraphArrayLengthCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphArrayLengthPackage])).stdout); const programGraphBlockBodyInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphBlockBodyPackage])).stdout); const programGraphBlockBodyMainPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addMain", ], { cwd: programGraphBlockBodyPackage })).stdout); const programGraphBlockBodyMainQuery = JSON.parse((await execFileAsync(zero, ["query", "--json", programGraphBlockBodyPackage])).stdout); const programGraphBlockBodyGreetingPatchText = [ "zero-program-graph-patch v1", `expect graphHash "${programGraphBlockBodyMainQuery.graphHash}"`, "replaceFunctionBody main", " let name Maybe = std.args.get 1", " if name.has", " check world.out.write \"hello \"", " check world.out.write name.value", " check world.out.write \"\\n\"", " else", " check world.out.write \"hello anonymous\\n\"", "end", "", ].join("\n"); const programGraphBlockBodyGreetingPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", programGraphBlockBodyPackage, "--patch-text", programGraphBlockBodyGreetingPatchText])).stdout); const programGraphBlockBodyBlocks = JSON.parse((await execFileAsync(zero, ["query", "--json", "--find", "Block", programGraphBlockBodyPackage])).stdout); const programGraphBlockBodyThen = programGraphBlockBodyBlocks.matches.find((node) => node.kind === "Block" && node.name === "then"); assert(programGraphBlockBodyThen, "expected row-patched greeting body to expose a then block handle"); const programGraphBlockBodyPatchText = [ "zero-program-graph-patch v1", `expect graphHash "${programGraphBlockBodyBlocks.graphHash}"`, `replaceBlockBody ${programGraphBlockBodyThen.id}`, " check world.out.write \"name + value: \"", " check world.out.write name.value", " check world.out.write \"\\n\"", "end", "", ].join("\n"); const programGraphBlockBodyDryRun = JSON.parse((await execFileAsync(zero, ["patch", "--json", "--check-only", programGraphBlockBodyPackage, "--patch-text", programGraphBlockBodyPatchText])).stdout); const programGraphBlockBodyPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", programGraphBlockBodyPackage, "--patch-text", programGraphBlockBodyPatchText])).stdout); const programGraphBlockBodyView = (await execFileAsync(zero, ["view", programGraphBlockBodyPackage])).stdout; const programGraphBlockBodyCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphBlockBodyPackage])).stdout); const programGraphBlockBodyRun = await execFileAsync(zero, ["run", "--out", programGraphBlockBodyRunPath, programGraphBlockBodyPackage, "--", "Ada"]); const programGraphAuthoringCliInit = JSON.parse((await execFileAsync(zero, ["init", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliProjectionExistsAfterInit = await fileExists(`${programGraphAuthoringCliPackage}/src/main.0`); const programGraphAuthoringCliPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addMain", "--op", "addFunction name=\"add_u32\" ret=\"u32\"", "--op", "addParam fn=\"add_u32\" name=\"x\" type=\"u32\"", "--op", "addParam fn=\"add_u32\" name=\"y\" type=\"u32\"", "--op", "addReturnBinary fn=\"add_u32\" name=\"+\" left=\"x\" right=\"y\" type=\"u32\"", ], { cwd: programGraphAuthoringCliPackage })).stdout); const programGraphAuthoringCliBodyQuery = JSON.parse((await execFileAsync(zero, ["query", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliBodyPatchText = [ "zero-program-graph-patch v1", `expect graphHash "${programGraphAuthoringCliBodyQuery.graphHash}"`, "replaceFunctionBody main", " let x Maybe = std.args.parseU32 1", " let y Maybe = std.args.parseU32 2", " if x.has && y.has", " let result u32 = add_u32 x.value y.value", " var out [10]u8 = repeat 0_u8 10", " let text Maybe> = std.fmt.u32 out result", " if text.has", " check world.out.write text.value", " check world.out.write \"\\n\"", " else", " check world.err.write \"usage: zero run . -- \\n\"", "end", "", ].join("\n"); const programGraphAuthoringCliBodyPatch = JSON.parse((await execFileAsync(zero, ["patch", "--json", programGraphAuthoringCliPackage, "--patch-text", programGraphAuthoringCliBodyPatchText])).stdout); const programGraphAuthoringCliProjectionExistsAfterPatch = await fileExists(`${programGraphAuthoringCliPackage}/src/main.0`); const programGraphAuthoringCliStaleAddPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "addFunction name=\"add\" ret=\"i32\"", "--op", "addParam fn=\"add\" name=\"x\" type=\"i32\"", "--op", "addParam fn=\"add\" name=\"y\" type=\"i32\"", "--op", "addReturnBinary fn=\"add\" name=\"+\" left=\"x\" right=\"y\" type=\"i32\"", "--op", "addTest name=\"add works\" call=\"add\" arg0=\"40\" arg1=\"2\" expect=\"42\" type=\"i32\"", ], { cwd: programGraphAuthoringCliPackage })).stdout); const programGraphAuthoringCliFindAdd = JSON.parse((await execFileAsync(zero, ["query", "--json", "--find", "add", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliNodeAdd = JSON.parse((await execFileAsync(zero, ["query", "--json", "--node", "#fn_add", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliCleanupPatch = JSON.parse((await execFileAsync(zero, [ "patch", "--json", "--op", "delete node=\"#fn___zero_test_0\"", "--op", "delete node=\"#fn_add\"", "--op", "addTest name=\"add_u32 works\" call=\"add_u32\" arg0=\"40\" arg1=\"2\" expect=\"42\" type=\"u32\"", ], { cwd: programGraphAuthoringCliPackage })).stdout); const programGraphAuthoringCliCallsText = (await execFileAsync(zero, ["query", "--fn", "main", "--calls", "std", programGraphAuthoringCliPackage])).stdout; const programGraphAuthoringCliRefsText = (await execFileAsync(zero, ["query", "--refs", "add_u32", programGraphAuthoringCliPackage])).stdout; const programGraphAuthoringCliQuery = JSON.parse((await execFileAsync(zero, ["query", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliGraphBuild = await execFileAsync(zero, ["build", "--out", programGraphAuthoringCliGraphBuildPath, programGraphAuthoringCliPackage]); const programGraphAuthoringCliBuild = await execFileAsync(zero, ["build", "--out", programGraphAuthoringCliBuildPath, programGraphAuthoringCliPackage]); const programGraphAuthoringCliTest = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliGraphTest = await execFileAsync(zero, ["test", programGraphAuthoringCliPackage]); const programGraphAuthoringCliRun = await execFileAsync(zero, ["run", "--out", programGraphAuthoringCliRunPath, programGraphAuthoringCliPackage, "--", "40", "2"]); const programGraphAuthoringCliGraphRun = await execFileAsync(zero, ["run", programGraphAuthoringCliPackage, "--", "7", "8"]); const programGraphAuthoringCliSize = JSON.parse((await execFileAsync(zero, ["size", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliSync = JSON.parse((await execFileAsync(zero, ["export", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliProjectionText = await readFile(`${programGraphAuthoringCliPackage}/src/main.0`, "utf8"); const programGraphAuthoringCliEditedProjectionText = programGraphAuthoringCliProjectionText.replace("usage: zero run . -- \\n", "usage: zero run . -- \\n"); await writeFile(`${programGraphAuthoringCliPackage}/src/main.0`, programGraphAuthoringCliEditedProjectionText); const programGraphAuthoringCliStatusAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["status", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliImport = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliQueryAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["query", "--json", "--calls", "std", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliFindUsageText = (await execFileAsync(zero, ["query", "--find", "usage", programGraphAuthoringCliPackage])).stdout; const programGraphAuthoringCliVerifyAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["verify-projection", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliCheckAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliTestAfterHumanEdit = JSON.parse((await execFileAsync(zero, ["test", "--json", programGraphAuthoringCliPackage])).stdout); const programGraphAuthoringCliRunAfterHumanEdit = await execFileAsync(zero, ["run", "--out", programGraphAuthoringCliRunAfterHumanEditPath, programGraphAuthoringCliPackage, "--", "5", "6"]); await mkdir(`${programGraphSourceFreeCImportPackage}/src`, { recursive: true }); await mkdir(`${programGraphSourceFreeCImportPackage}/vendor/include`, { recursive: true }); await writeZeroToml(programGraphSourceFreeCImportPackage, { package: { name: "program-graph-source-free-c-import", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { ext: { headers: ["vendor/include/zero_ext.h"], include: ["vendor/include"], lib: [], link: [], mode: "static" }, }, }, }); await writeFile(`${programGraphSourceFreeCImportPackage}/vendor/include/zero_ext.h`, "int zero_ext_add(int a, int b);\n"); await writeFile(`${programGraphSourceFreeCImportPackage}/src/main.0`, `extern c "vendor/include/zero_ext.h" as c pub fn main(world: World) -> Void raises { check world.out.write("source-free c import ok\\n") } `); const programGraphSourceFreeCImportSync = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphSourceFreeCImportPackage])).stdout); await rm(`${programGraphSourceFreeCImportPackage}/src`, { recursive: true, force: true }); const programGraphSourceFreeCImportCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphSourceFreeCImportPackage])).stdout); const programGraphSourceFreeCImportRun = await execFileAsync(zero, ["run", "--out", programGraphSourceFreeCImportRunPath, programGraphSourceFreeCImportPackage]); await mkdir(programGraphSourceFreeCImportCwdPackage, { recursive: true }); await writeZeroToml(programGraphSourceFreeCImportCwdPackage, { package: { name: "program-graph-source-free-c-import-cwd", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, }); const programGraphSourceFreeCImportCwdBuild = JSON.parse((await execFileAsync(resolve(zero), [ "build", "--json", "--out", resolve(programGraphSourceFreeCImportCwdBuildPath), resolve(programGraphSourceFreeCImportPackage), ], { cwd: programGraphSourceFreeCImportCwdPackage })).stdout); await mkdir(programGraphIdentityMismatchPackage, { recursive: true }); await writeZeroToml(programGraphIdentityMismatchPackage, { package: { name: "program-graph-wrong-package", version: "9.9.9" }, targets: { cli: { kind: "exe", main: "hello.0" } }, }); await writeFile(`${programGraphIdentityMismatchPackage}/zero.graph`, programGraphSourceFixtureStoreBytes); const programGraphIdentityMismatchCheck = await execFileAsync(zero, ["check", "--json", programGraphIdentityMismatchPackage]).catch((error) => error); const programGraphIdentityMismatchSize = await execFileAsync(zero, ["size", "--json", programGraphIdentityMismatchPackage]).catch((error) => error); await mkdir(programGraphMissingPackageNamePackage, { recursive: true }); await writeZeroToml(programGraphMissingPackageNamePackage, { targets: { cli: { kind: "exe", main: "hello.0" } }, }); await writeFile(`${programGraphMissingPackageNamePackage}/zero.graph`, programGraphSourceFixtureStoreBytes); const programGraphMissingPackageNameCheck = await execFileAsync(zero, ["check", "--json", programGraphMissingPackageNamePackage]).catch((error) => error); await mkdir(programGraphBadProjectionPackage, { recursive: true }); await writeFile(`${programGraphBadProjectionPackage}/zero.toml`, await readFile(`${programGraphSourceFixturePackage}/zero.toml`, "utf8")); await writeFile(`${programGraphBadProjectionPackage}/hello.0`, programGraphSourceFixtureText); await execFileAsync(zero, ["import", "--format", "text", programGraphBadProjectionPackage]); const programGraphBadProjectionStoreText = await readFile(`${programGraphBadProjectionPackage}/zero.graph`, "utf8"); await writeFile(`${programGraphBadProjectionPackage}/zero.graph`, programGraphBadProjectionStoreText.replace( /^projection path:"hello\.0" text:.*$/m, `projection path:"hello.0" text:${JSON.stringify("pub fn broken( {\n")}`, )); const programGraphBadProjectionStatus = JSON.parse((await execFileAsync(zero, ["status", "--json", programGraphBadProjectionPackage])).stdout); const programGraphBadProjectionCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphBadProjectionPackage])).stdout); const programGraphBadProjectionSync = await execFileAsync(zero, ["export", "--json", programGraphBadProjectionPackage]).catch((error) => error); await mkdir(programGraphMissingStorePackage, { recursive: true }); await writeZeroToml(programGraphMissingStorePackage, { package: { name: "program-graph-missing-store", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "main.0" } }, }); await writeFile(`${programGraphMissingStorePackage}/main.0`, "pub fn main() -> i32 { return 0 }\n"); const programGraphMissingStoreCheck = await execFileAsync(zero, ["check", "--json", programGraphMissingStorePackage]).catch((error) => error); await mkdir(programGraphInvalidStorePackage, { recursive: true }); await writeZeroToml(programGraphInvalidStorePackage, { package: { name: "program-graph-invalid-store", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "main.0" } }, }); await writeFile(`${programGraphInvalidStorePackage}/main.0`, "pub fn main() -> i32 { return 0 }\n"); await writeFile(`${programGraphInvalidStorePackage}/zero.graph`, "not a repository graph\n"); const programGraphInvalidStoreCheck = await execFileAsync(zero, ["check", "--json", programGraphInvalidStorePackage]).catch((error) => error); await mkdir(programGraphSourceFixtureDriftPackage, { recursive: true }); await writeFile(`${programGraphSourceFixtureDriftPackage}/zero.toml`, await readFile(`${programGraphSourceFixturePackage}/zero.toml`, "utf8")); await writeFile(`${programGraphSourceFixtureDriftPackage}/zero.graph`, programGraphSourceFixtureStoreBytes); await writeFile(`${programGraphSourceFixtureDriftPackage}/hello.0`, programGraphSourceFixtureText.replace("hello from zero", "hello from drift")); const programGraphSourceFixtureDriftVerify = await execFileAsync(zero, ["verify-projection", "--json", programGraphSourceFixtureDriftPackage]).catch((error) => error); const programGraphSourceFixtureDriftCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", programGraphSourceFixtureDriftPackage])).stdout); const programGraphSourceFixtureDriftVerifyAfterRefresh = JSON.parse((await execFileAsync(zero, ["verify-projection", "--json", programGraphSourceFixtureDriftPackage])).stdout); await mkdir(programGraphTargetWebbitsPackage, { recursive: true }); await writeFile(`${programGraphTargetWebbitsPackage}/zero.toml`, await readFile("conformance/packages/target-webbits/zero.toml", "utf8")); await mkdir(`${programGraphTargetIncompatiblePackage}/src`, { recursive: true }); await writeZeroToml(programGraphTargetIncompatiblePackage, { package: { name: "program-graph-target-incompatible", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, dependencies: { "target-webbits": { path: "../program-graph-target-webbits", version: "0.1.0", targets: ["win32-x64.exe"] } }, }); await writeFile(`${programGraphTargetIncompatiblePackage}/src/main.0`, `pub fn main(world: World) -> Void raises { check world.out.write("target incompatible\\n") } `); const programGraphTargetIncompatibleSync = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphTargetIncompatiblePackage])).stdout); const programGraphTargetIncompatibleCheck = await execFileAsync(zero, ["check", "--json", "--target", "linux-musl-x64", programGraphTargetIncompatiblePackage]).catch((error) => error); await mkdir(programGraphTargetCapabilityPackage, { recursive: true }); await writeZeroToml(programGraphTargetCapabilityPackage, { package: { name: "program-graph-target-capability", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "main.0" } }, }); await writeFile(`${programGraphTargetCapabilityPackage}/main.0`, `pub fn main(world: World) -> Void raises { let fs: Fs = std.fs.host() if std.fs.writeFile(fs, ".zero/out/program-graph-target-capability.txt", "ok\\n") { check world.out.write("ok\\n") } } `); const programGraphTargetCapabilitySync = JSON.parse((await execFileAsync(zero, ["import", "--json", programGraphTargetCapabilityPackage])).stdout); const programGraphTargetCapabilityCheck = await execFileAsync(zero, ["check", "--json", "--target", "linux-arm64", programGraphTargetCapabilityPackage]).catch((error) => error); await execFileAsync(zero, ["dump", "--out", programGraphRichPath, "conformance/native/pass/open-ended-slices.0"]); await execFileAsync(zero, ["view", "--out", programGraphRichViewPath, programGraphRichPath]); const programGraphRichView = await readFile(programGraphRichViewPath, "utf8"); await execFileAsync(zero, ["dump", "--out", programGraphCharPath, "conformance/native/pass/float-char-casts.0"]); await execFileAsync(zero, ["view", "--out", programGraphCharViewPath, programGraphCharPath]); const programGraphCharView = await readFile(programGraphCharViewPath, "utf8"); const programGraphViewCoverage = [ ["compile-time-v1", "examples/compile-time-v1.0", [/const field_type: String = meta fieldType\(Point, "x"\)/, /readGate\(&gate\)/]], ["array-repeat-literal", "conformance/native/pass/array-repeat-literal.0", [/\[7_u8; 8\]/, /\[0_u8; 16\]/]], ["explicit-casts", "conformance/native/pass/explicit-casts.0", [/let byte: u8 = big as u8/, /let offset: isize = small as isize/]], ["generic-multi-specialization", "conformance/native/pass/generic-multi-specialization.0", [/first\(21, 7\)/, /second\(a, 6\)/]], ["generic-shape-nested-defaults-alias", "conformance/native/pass/generic-shape-nested-defaults-alias.0", [/Box \{ value: 42 \}/, /Slot \{ item: 7_u8 \}/]], ["float-primitives", "conformance/native/pass/float-primitives.0", [/let precise: f64 = 1\.0e-3/]], ["meta-typed-target-type", "conformance/native/pass/meta-typed-target-type.0", [/const computed: usize = meta 2 \+ 2/]], ["nested-lvalues", "conformance/native/pass/nested-lvalues.0", [/Point \{ x: 3, y: 4 \}/, /Point \{ x: 5, y: 6 \}/]], ["radix-suffix-literals", "conformance/native/pass/radix-suffix-literals.0", [/return 0x20_usize/, /1_024_usize/, /0x2a_u8/]], ["test-blocks", "conformance/native/pass/test-blocks.0", [/test "addition works"/]], ["type-alias-basic", "conformance/native/pass/type-alias-basic.0", [/let count: ByteCount = 4_usize/]], ["c-abi-export", "conformance/native/pass/c-abi-export.0", [/extern type CPoint/, /export c fn zero_add\(a: i32, b: i32\) -> i32/]], ["const-layout", "conformance/native/pass/const-layout.0", [/extern type CPoint/, /packed type Header/]], ["c-header-import", "conformance/check/pass/c-header-import.0", [/extern c "conformance\/c\/simple\.h" as c/]], ["constructors-defaults", "conformance/native/pass/constructors-defaults.0", [/FixedVec\.init/]], ["direct-call-add", "examples/direct-call-add.0", [/export c fn main\(a: i32, b: i32\) -> i32/]], ["generic-static-explicit-shadowing", "conformance/check/pass/generic-static-explicit-shadowing.0", [/Helper\.needsSame\(left, right\)/]], ["systems-package", "examples/systems-package", [/use std\.codec/, /pub fn main\(world: World\) -> Void raises/]], ["std-math", "examples/std-math.0", [/pub fn main\(world: World\) -> Void raises/, /std\.math\.minU32\(8, 3\)/]], ]; for (const [name, fixture, patterns] of programGraphViewCoverage) { const graphPath = `${outDir}/${name}.program-graph`; const viewPath = `${outDir}/${name}.graph-view.0`; await rm(graphPath, { force: true }); await rm(viewPath, { force: true }); await execFileAsync(zero, ["dump", "--out", graphPath, fixture]); await execFileAsync(zero, ["view", "--out", viewPath, graphPath]); const view = await readFile(viewPath, "utf8"); for (const pattern of patterns) assert.match(view, pattern); assert.doesNotMatch(view, /fn __zero_test_/); if (name === "systems-package") { assert.doesNotMatch(view, /^use (helpers|types)$/m); await execFileAsync(zero, ["import", "--format", "binary", "--out", graphSidecarPath(viewPath), viewPath]); assert.equal((await execFileAsync(zero, ["check", viewPath])).stdout, "ok\n"); } if (name === "std-math") assert.doesNotMatch(view, /fn __zero_std_/); } for (const fixture of [ "conformance/native/pass/open-ended-slices.0", "conformance/native/pass/float-char-casts.0", "conformance/check/pass/call-resolution-edge-cases.0", "conformance/native/pass/match-payload-binding.0", "conformance/native/pass/match-scalar-guards.0", "conformance/native/pass/rescue-check.0", "examples/result-choice.0", "examples/compile-time-v1.0", "examples/config-shape.0", "examples/direct-enum-match.0", "conformance/native/pass/test-blocks.0", "examples/std-math.0", "examples/systems-package", "std/math.0", "std/path.0", "std/str.0", ]) { const roundtrip = JSON.parse((await execFileAsync(zero, ["roundtrip", "--json", fixture])).stdout); assert.equal(roundtrip.ok, true); assert.equal(roundtrip.semanticStable, true); assert.equal(roundtrip.roundtripModuleIdentity, roundtrip.moduleIdentity); assert.equal(roundtrip.comparison.ok, true); assert.deepEqual(roundtrip.semanticCounts.original, roundtrip.semanticCounts.roundtrip); } const stdPathRecursiveView = (await execFileAsync(zero, ["view", "conformance/native/pass/std-path-io-breadth.0"])).stdout; assert.match(stdPathRecursiveView, /std\.path\.relative\(rel_buf, "src", "src\/main\.0"\)/); assert.doesNotMatch(stdPathRecursiveView, /__zero_std_/); assert.equal(programGraphBody.schemaVersion, 1); assert.equal(programGraphBody.canonicalSource, false); assert.equal(programGraphBody.moduleIdentity, "module:hello"); assert.deepEqual(programGraphBodyAgain, programGraphBody); assert.equal(programGraphBody.resolution.state, "resolved"); assert.equal(programGraphBody.resolution.ok, true); assert(programGraphBody.resolution.scopes.some((scope) => scope.kind === "module" && scope.name === "hello" && scope.bindings.some((binding) => binding.kind === "function" && binding.name === "main"))); assert(programGraphBody.resolution.references.some((reference) => reference.kind === "identifier" && reference.name === "world" && reference.targetKind === "param" && reference.symbolId === "symbol:hello::value.main/param.world")); assert(programGraphBody.resolution.references.some((reference) => reference.kind === "call" && reference.qualifiedName === "world.out.write" && reference.targetKind === "member")); assert.equal(programGraphBody.semantics.state, "typed-facts"); assert.equal(programGraphBody.semantics.ok, true); assert(programGraphBody.semantics.functions.some((item) => item.name === "main" && item.returnType === "Void" && item.fallible === true && item.sourceRange.path === "hello.0" && item.params.some((param) => param.name === "world" && param.type === "World" && param.sourceRange.path === "hello.0"))); assert(programGraphBody.semantics.calls.some((item) => item.qualifiedName === "world.out.write" && item.returnType === "Void" && item.fallible === true && item.checked === true && item.sourceRange.path === "hello.0" && item.contract.kind === "worldStreamWrite" && item.contract.capability === "io" && item.contract.targetSupport === "world-io" && item.contract.repair?.id === "check-fallible-call" && item.resolution.targetKind === "member" && item.resolution.symbolId === "symbol:hello::value.main/param.world")); assert(programGraphBody.semantics.ownership.some((item) => item.name === "world" && item.ownership === "resource-handle" && item.resource === true)); assert(programGraphBody.semantics.resources.some((item) => item.kind === "capabilityUse" && item.resourceKind === "world-io" && item.qualifiedName === "world.out.write")); assert(programGraphBody.semantics.targetRequirements.some((item) => item.qualifiedName === "world.out.write" && item.capability === "io" && item.targetSupport === "world-io")); assert(programGraphBody.semantics.repairs.some((item) => item.qualifiedName === "world.out.write" && item.requiresCheck === false && item.repair.id === "check-fallible-call")); assert.equal(programGraphDumpAgain, programGraphDump); assert.equal(programGraphDumpOut.stdout, ""); assert.equal(programGraphDumpFile, programGraphDump); assert.deepEqual(programGraphDumpOutJson, programGraphDumpJson); assert.equal(programGraphDumpJsonFile, programGraphDump); assert.equal(programGraphValidate.stdout, "program graph ok\n"); assert.equal(programGraphDumpJsonValidate.stdout, "program graph ok\n"); assert.equal(programGraphCanonicalFile, programGraphDump); assert.equal(programGraphValidateJson.ok, true); assert.equal(programGraphValidateJson.moduleIdentity, "module:hello"); assert.equal(programGraphValidateJson.graphHash, programGraphBody.graphHash); assert.equal(programGraphValidateJson.saved.path, programGraphCanonicalPath); assert.equal(programGraphViewAgain, programGraphView); assert.equal(programGraphViewOut.stdout, ""); assert.equal(programGraphViewFile, programGraphView); assert.equal(programGraphViewJson.ok, true); assert.equal(programGraphViewJson.canonicalSource, false); assert.equal(programGraphViewJson.moduleIdentity, "module:hello"); assert.equal(programGraphViewJson.graphHash, programGraphBody.graphHash); assert.equal(programGraphViewJson.view, programGraphView); assert.equal(programGraphViewOutJson.ok, true); assert.equal(programGraphViewOutJson.saved.path, programGraphViewPath); assert.equal(programGraphViewOutJson.view, null); assert.equal(programGraphRoundtrip.stdout, "program graph roundtrip ok\n"); assert.equal(programGraphRoundtripJson.ok, true); assert.equal(programGraphRoundtripJson.canonicalSource, false); assert.equal(programGraphRoundtripJson.semanticStable, true); assert.equal(programGraphRoundtripJson.lowering, "direct-program-graph"); assert.equal(programGraphRoundtripJson.moduleIdentity, "module:hello"); assert.equal(programGraphRoundtripJson.roundtripModuleIdentity, "module:hello"); assert.equal(programGraphRoundtripJson.originalGraphHash, programGraphBody.graphHash); assert.equal(programGraphRoundtripJson.roundtripGraphHash, programGraphBody.graphHash); assert.deepEqual(programGraphRoundtripJson.semanticCounts.original, programGraphRoundtripJson.semanticCounts.roundtrip); assert.equal(programGraphRoundtripJson.comparison.ok, true); assert.equal(programGraphRoundtripJson.view, null); assert.equal(programGraphArtifactRoundtrip.stdout, "program graph roundtrip ok\n"); assert.equal(programGraphArtifactRoundtripJson.ok, true); assert.equal(programGraphArtifactRoundtripJson.artifact, programGraphDumpPath); assert.equal(programGraphArtifactRoundtripJson.semanticStable, true); assert.equal(programGraphArtifactRoundtripJson.lowering, "direct-program-graph"); assert.equal(programGraphArtifactRoundtripJson.originalGraphHash, programGraphBody.graphHash); assert.equal(programGraphArtifactRoundtripJson.roundtripGraphHash, programGraphBody.graphHash); assert.equal(programGraphArtifactRoundtripJson.saved.path, programGraphArtifactRoundtripPath); assert.equal(programGraphArtifactRoundtripJson.saved.kind, "program-graph"); assert.equal(programGraphArtifactRoundtripJson.view, null); assert.equal(await readFile(programGraphArtifactRoundtripPath, "utf8"), programGraphDump); assert.equal(programGraphSourceFixtureText, await readFile("examples/hello.0", "utf8")); assert.equal(programGraphSourceFixturePackageCheckJson.ok, true); assert.equal(programGraphSourceFixturePackageCheckJson.sourceFile, programGraphSourceFixtureStorePath); assert.equal(programGraphSourceFixturePackageCheckJson.package.name, "program-graph-fixture"); assert.equal(programGraphSourceFixturePackageCheckJson.graph.artifact, programGraphSourceFixtureStorePath); assert.equal(programGraphSourceFixturePackageCheckJson.graph.canonicalSource, false); assert.equal(programGraphSourceFixturePackageCheckJson.graph.moduleIdentity, "package:program-graph-fixture@0.1.0"); assert.match(programGraphSourceFixturePackageCheckJson.graph.graphHash, /^graph:[0-9a-f]{16}$/); assert.equal(programGraphSourceFixturePackageCheckJson.graph.lowering, "graph-native-check"); assert.equal(programGraphSourceFixturePackageStatusJson.store.encoding, "binary"); assert.equal(programGraphSourceFixturePackageStatusJson.storage.encoding, "single-file-binary"); assertRepositoryGraphNativeCheck(programGraphSourceFixturePackageCheckJson); assert.equal(programGraphSourceFixturePackageRun.stdout, "hello from zero\n"); assert.equal(programGraphSourceFreeCheckJson.ok, true); assert.equal(programGraphSourceFreeCheckJson.sourceFile, `${programGraphSourceFreePackage}/zero.graph`); assert.equal(programGraphSourceFreeCheckJson.graph.artifact, `${programGraphSourceFreePackage}/zero.graph`); assert.equal(programGraphSourceFreeCheckJson.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphSourceFreeCheckJson, "missing"); assertProgramGraphCompilerInput(programGraphSourceFreeCheckJson, `${programGraphSourceFreePackage}/zero.graph`); assertSourceGraph(programGraphSourceFreeSizeJson, `${programGraphSourceFreePackage}/zero.graph`, "package:program-graph-fixture@0.1.0", "mapped-final-mir", false, "missing"); assertProgramGraphCompilerInput(programGraphSourceFreeSizeJson, `${programGraphSourceFreePackage}/zero.graph`); assert.equal(programGraphSourceFreeBuildJson.sourceFile, `${programGraphSourceFreePackage}/zero.graph`); assertSourceGraph(programGraphSourceFreeBuildJson, `${programGraphSourceFreePackage}/zero.graph`, "package:program-graph-fixture@0.1.0", "mapped-final-mir", false, "missing"); assertProgramGraphCompilerInput(programGraphSourceFreeBuildJson, `${programGraphSourceFreePackage}/zero.graph`); assert(programGraphSourceFreeMappedMirCachePath.endsWith(".zmir"), "repository graph build should report a mapped MIR cache path"); assert.equal(existsSync(programGraphSourceFreeMappedMirCachePath), true, "repository graph build should write a mapped MIR cache"); assert.equal(programGraphSourceFreeRun.stdout, "hello from zero\n"); assert.equal(programGraphSourceFreeTestJson.ok, true); assertSourceGraph(programGraphSourceFreeTestJson, `${programGraphSourceFreePackage}/zero.graph`, "package:program-graph-fixture@0.1.0", "direct-program-graph", false, "missing"); assert.equal(programGraphSourceFreeTestJson.testBackend, "direct-program-graph"); assert.equal(programGraphSourceFreeTestJson.testDiscovery.mode, "package-graph"); assertSourceGraph(programGraphSourceFreeMemJson, `${programGraphSourceFreePackage}/zero.graph`, "package:program-graph-fixture@0.1.0", "mapped-final-mir", false, "missing"); assertProgramGraphCompilerInput(programGraphSourceFreeMemJson, `${programGraphSourceFreePackage}/zero.graph`); assert.notEqual(programGraphSourceFreeVerify.code, 0); const programGraphSourceFreeVerifyBody = JSON.parse(programGraphSourceFreeVerify.stdout); assert.equal(programGraphSourceFreeVerifyBody.diagnostics[0].code, "RGP006"); assert.equal(programGraphSourceFreeVerifyBody.diagnostics[0].actual, "missing source projection file"); assert.match(programGraphSourceFreeVerifyBody.repairCommands.join("\n"), /zero export/); assert.equal(programGraphSourceFreeExport.ok, true); assert.deepEqual(programGraphSourceFreeExport.changedPaths, [`${programGraphSourceFreePackage}/hello.0`]); assert.equal(await readFile(`${programGraphSourceFreePackage}/hello.0`, "utf8"), programGraphSourceFixtureText); assert.equal(programGraphSourceFreeVerifyAfter.ok, true); assert.equal(programGraphSourceFreeVerifyAfter.repositoryGraph.projectionValidity, "clean"); assert.equal(programGraphSourceFreeStdStrSync.ok, true); assert.equal(programGraphSourceFreeStdStrCheckJson.ok, true); assertSourceGraph(programGraphSourceFreeStdStrCheckJson, `${programGraphSourceFreeStdStrPackage}/zero.graph`, "package:program-graph-source-free-std-str@0.1.0", "graph-native-check", false, "missing"); assertProgramGraphCompilerInput(programGraphSourceFreeStdStrCheckJson, `${programGraphSourceFreeStdStrPackage}/zero.graph`); assertRepositoryGraphNativeCheck(programGraphSourceFreeStdStrCheckJson, "missing"); assert.equal(programGraphSourceFreeStdStrCheckJson.targetReadiness.ok, true); assert.equal(programGraphSourceFreeStdStrCheckJson.targetReadiness.diagnostics.length, 0); assert(programGraphSourceFreeStdStrCheckJson.graphCompiler.semanticFacts.calls.some((call) => call.qualifiedName === "std.str.reverse" && call.contract.kind === "stdlib" && call.resolution.targetKind === "stdlib" && call.returnType === "Maybe>")); assert.equal(programGraphCrmApiCheckJson.ok, true); assert.equal(programGraphCrmApiStatusJson.store.encoding, "binary"); assert.equal(programGraphCrmApiStatusJson.storage.encoding, "single-file-binary"); assert.equal(programGraphCrmApiStatusJson.repositoryGraph.projectionValidity, "clean"); assert.equal(programGraphCrmApiCheckJson.sourceFile, "examples/crm-api/zero.graph"); assertSourceGraph(programGraphCrmApiCheckJson, "examples/crm-api/zero.graph", "package:crm-api@0.1.0", "graph-native-check", false, "clean"); assertRepositoryGraphNativeCheck(programGraphCrmApiCheckJson, "clean"); assert.equal(programGraphCrmApiBuildJson.sourceFile, "examples/crm-api/zero.graph"); assertSourceGraph(programGraphCrmApiBuildJson, "examples/crm-api/zero.graph", "package:crm-api@0.1.0", "mapped-final-mir", false, "clean"); assert.equal(programGraphCrmApiBuildJson.generatedCBytes, 0); assert.equal(programGraphCrmApiBuildJson.incrementalInvalidation.sourceKind, "program-graph"); assert.equal(programGraphCrmApiBuildJson.incrementalInvalidation.graphInput.parserArtifactsInKey, false); assert.equal(programGraphCrmApiHealth.stdout, "HTTP/1.1 200 OK\r\ncontent-type: application/json\r\nconnection: close\r\ncontent-length: 27\r\n\r\n{\"ok\":true,\"service\":\"crm\"}"); assert.match(programGraphCrmApiAccounts.stdout, /"accounts":\[/); assert.match(programGraphCrmApiDealUpdate.stdout, /"updated":true/); assert.match(programGraphCrmApiMissing.stdout, /^HTTP\/1\.1 404 Not Found\r\n/); assert.equal(programGraphAuthoringInit.ok, true); assert.equal(programGraphAuthoringInit.compilerInput, "repository-graph"); assert.equal(programGraphAuthoringInit.sourceProjection.path, "src/main.0"); assert.equal(programGraphAuthoringInit.sourceProjection.materialized, false); assert.equal(programGraphAuthoringProjectionExistsAfterInit, false); assert.equal(programGraphAuthoringPatch.ok, true); assert.equal(programGraphAuthoringPatch.operationCount, 7); assert.equal(programGraphAuthoringPatch.artifact, "./zero.graph"); assert.equal(programGraphAuthoringPatch.saved.path, "./zero.graph"); assert.equal(programGraphAuthoringProjectionExistsAfterPatch, false); assert.equal(programGraphAuthoringStatusMissing.repositoryGraph.projectionState, "source-missing"); assert.equal(programGraphAuthoringStatusMissing.repositoryGraph.projectionValidity, "missing"); assert.notEqual(programGraphAuthoringVerifyMissing.code, 0); const programGraphAuthoringVerifyMissingBody = JSON.parse(programGraphAuthoringVerifyMissing.stdout); assert.equal(programGraphAuthoringVerifyMissingBody.diagnostics[0].code, "RGP006"); assert.equal(programGraphAuthoringVerifyMissingBody.diagnostics[0].actual, "missing source projection file"); assert.match(programGraphAuthoringVerifyMissingBody.repairCommands.join("\n"), /zero export/); assert.equal(programGraphAuthoringCheck.ok, true); assert.equal(programGraphAuthoringCheck.sourceFile, `${programGraphAuthoringPackage}/zero.graph`); assert.equal(programGraphAuthoringCheck.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphAuthoringCheck, "missing"); assertProgramGraphCompilerInput(programGraphAuthoringCheck, `${programGraphAuthoringPackage}/zero.graph`); assert.equal(programGraphAuthoringRun.stdout, "graph authoring ok\n"); assert.equal(programGraphAuthoringTest.ok, true); assert.equal(programGraphAuthoringTest.testDiscovery.mode, "package-graph"); assert.equal(programGraphAuthoringTest.passedTests, 1); assert.equal(programGraphAuthoringExport.ok, true); assert.equal(programGraphAuthoringExport.repositoryGraph.projectionState, "clean"); assert.deepEqual(programGraphAuthoringExport.changedPaths, [`${programGraphAuthoringPackage}/src/main.0`]); assert.match(programGraphAuthoringProjectionText, /pub fn main\(world: World\) -> Void raises \{/); assert.match(programGraphAuthoringProjectionText, /fn add\(left: i32, right: i32\) -> i32/); assert.match(programGraphAuthoringProjectionText, /test "addition works"/); assert.equal(programGraphAuthoringVerifyAfter.ok, true); assert.equal(programGraphAuthoringVerifyAfter.repositoryGraph.projectionState, "clean"); assert.equal(programGraphAuthoringCheckAfter.ok, true); assert.equal(programGraphAuthoringCheckAfter.graph.sourceProjectionState, "clean"); assert.equal(programGraphAuthoringStatusAfterHumanEdit.repositoryGraph.projectionState, "source-stale"); assert.equal(programGraphAuthoringImport.ok, true); assert.equal(programGraphAuthoringImport.repositoryGraph.projectionState, "clean"); assert.deepEqual(programGraphAuthoringImport.changedPaths, [`${programGraphAuthoringPackage}/zero.graph`]); assert.equal(programGraphAuthoringCheckAfterHumanEdit.ok, true); assert.equal(programGraphAuthoringCheckAfterHumanEdit.graph.sourceProjectionState, "clean"); assert.equal(programGraphAuthoringRunAfterHumanEdit.stdout, "human edit ok\n"); assert.equal(programGraphBuilderOpsInit.ok, true); assert.equal(programGraphBuilderOpsInit.sourceProjection.materialized, false); assert.equal(programGraphBuilderOpsPatch.ok, true); assert.equal(programGraphBuilderOpsPatch.operationCount, 10); assert.equal(programGraphBuilderOpsProjectionExistsAfterPatch, false); assert.equal(programGraphBuilderOpsQuery.ok, true); assert(programGraphBuilderOpsQuery.functions.some((fun) => fun.name === "add_twice" && fun.returnType === "u32")); assert(programGraphBuilderOpsQuery.patchOperations.includes("addLetLiteral fn=\"main\" name=\"count\" type=\"u32\" value=\"0\"")); assert(programGraphBuilderOpsQuery.patchOperations.includes("addLetBinary fn=\"add\" name=\"sum\" type=\"i32\" operator=\"+\" left=\"left\" right=\"right\"")); assert(programGraphBuilderOpsQuery.patchOperations.includes("addReturnValue fn=\"identity\" value=\"input\" type=\"i32\"")); assert(programGraphBuilderOpsQuery.patchOperations.includes("addCheckWriteValue fn=\"main\" value=\"message\" type=\"String\"")); assert.match(programGraphBuilderOpsView, /let message: String = "graph value write ok\\n"/); assert.match(programGraphBuilderOpsView, /check world\.out\.write\(message\)/); assert.match(programGraphBuilderOpsView, /let first: u32 = x \+ y/); assert.match(programGraphBuilderOpsView, /let total: u32 = first \+ y/); assert.match(programGraphBuilderOpsView, /return total/); assert.equal(programGraphBuilderOpsCheck.ok, true); assert.equal(programGraphBuilderOpsCheck.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphBuilderOpsCheck, "missing"); assert.equal(programGraphBuilderOpsTest.ok, true); assert.equal(programGraphBuilderOpsTest.passedTests, 1); assert.equal(programGraphBuilderOpsRun.stdout, "graph value write ok\n"); assert.equal(programGraphBuilderOpsSync.ok, true); assert.deepEqual(programGraphBuilderOpsSync.changedPaths, [`${programGraphBuilderOpsPackage}/src/main.0`]); assert.equal(programGraphBuilderOpsProjectionText, programGraphBuilderOpsView); assert.equal(programGraphLoopTestInit.ok, true); assert.equal(programGraphLoopTestPatch.ok, true); assert.equal(programGraphLoopTestBodyPatch.ok, true); assert.equal(programGraphLoopTestBodyPatch.operations[0].op, "replaceFunctionBody"); assert.equal(programGraphLoopTestAddTest.ok, true); assert.equal(programGraphLoopTestCheck.ok, true); assert.equal(programGraphLoopTestCheck.sourceFile, `${programGraphLoopTestPackage}/zero.graph`); assertRepositoryGraphNativeCheck(programGraphLoopTestCheck, "missing"); assert.equal(programGraphLoopTestRun.ok, true); assert.equal(programGraphLoopTestRun.testBackend, "direct-program-graph"); assert.equal(programGraphLoopTestRun.passedTests, 1); assert.match(programGraphLoopTestView, /while i < n \{/); assert.match(programGraphLoopTestView, /i = i \+ 1/); assert.equal(programGraphArrayLengthInit.ok, true); assert.equal(programGraphArrayLengthMainPatch.ok, true); assert.equal(programGraphArrayLengthRepeatPatch.ok, false); assert.equal(programGraphArrayLengthRepeatPatch.diagnostics[0].code, "TYP002"); assert.equal(programGraphArrayLengthRepeatPatch.diagnostics[0].expected, "[64]u8"); assert.equal(programGraphArrayLengthRepeatPatch.diagnostics[0].actual, "repeat count 32"); assert.match(programGraphArrayLengthRepeatPatch.diagnostics[0].help, /make the lengths agree/); assert.equal(programGraphArrayLengthListPatch.ok, false); assert.equal(programGraphArrayLengthListPatch.diagnostics[0].code, "TYP002"); assert.equal(programGraphArrayLengthListPatch.diagnostics[0].expected, "[4]u8"); assert.equal(programGraphArrayLengthListPatch.diagnostics[0].actual, "2 element(s)"); assert.equal(programGraphArrayLengthMatchingPatch.ok, true); assert.equal(programGraphArrayLengthCheck.ok, true); assertRepositoryGraphNativeCheck(programGraphArrayLengthCheck, "missing"); assert.equal(programGraphBlockBodyInit.ok, true); assert.equal(programGraphBlockBodyMainPatch.ok, true); assert.equal(programGraphBlockBodyMainPatch.operationCount, 1); assert.equal(programGraphBlockBodyGreetingPatch.ok, true); assert.equal(programGraphBlockBodyGreetingPatch.operationCount, 1); assert.equal(programGraphBlockBodyGreetingPatch.operations[0].op, "replaceFunctionBody"); assert.equal(programGraphBlockBodyBlocks.ok, true); assert(programGraphBlockBodyBlocks.patchOperations.some((op) => op.startsWith("replaceBlockBody #block_id\n"))); assert.equal(programGraphBlockBodyDryRun.ok, true); assert.equal(programGraphBlockBodyDryRun.checkOnly, true); assert.equal(programGraphBlockBodyDryRun.saved, null); assert.equal(programGraphBlockBodyPatch.ok, true); assert.equal(programGraphBlockBodyPatch.operationCount, 1); assert.equal(programGraphBlockBodyPatch.operations[0].op, "replaceBlockBody"); assert.match(programGraphBlockBodyView, /if name\.has \{/); assert.match(programGraphBlockBodyView, /check world\.out\.write\("name \+ value: "\)/); assert.match(programGraphBlockBodyView, /check world\.out\.write\("hello anonymous\\n"\)/); assert.equal(programGraphBlockBodyCheck.ok, true); assert.equal(programGraphBlockBodyCheck.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphBlockBodyCheck, "missing"); assert.equal(programGraphBlockBodyRun.stdout, "name + value: Ada\n"); assert.equal(programGraphAuthoringCliInit.ok, true); assert.equal(programGraphAuthoringCliInit.sourceProjection.materialized, false); assert.equal(programGraphAuthoringCliPatch.ok, true); assert.equal(programGraphAuthoringCliPatch.operationCount, 5); assert.equal(programGraphAuthoringCliBodyPatch.ok, true); assert.equal(programGraphAuthoringCliBodyPatch.operationCount, 1); assert.equal(programGraphAuthoringCliBodyPatch.operations[0].op, "replaceFunctionBody"); assert.equal(programGraphAuthoringCliProjectionExistsAfterInit, false); assert.equal(programGraphAuthoringCliProjectionExistsAfterPatch, false); assert.equal(programGraphAuthoringCliStaleAddPatch.ok, true); assert.equal(programGraphAuthoringCliStaleAddPatch.operationCount, 5); assert.equal(programGraphAuthoringCliFindAdd.ok, true); assert(programGraphAuthoringCliFindAdd.matches.some((node) => node.id === "#fn_add" && node.kind === "Function")); assert(programGraphAuthoringCliFindAdd.matches.some((node) => node.id === "#fn___zero_test_0" && node.kind === "Function" && node.value === "add works")); assert.equal(programGraphAuthoringCliNodeAdd.ok, true); assert.equal(programGraphAuthoringCliNodeAdd.query.node, "#fn_add"); assert.equal(programGraphAuthoringCliNodeAdd.node.selected.id, "#fn_add"); assert(programGraphAuthoringCliNodeAdd.node.parents.some((edge) => edge.kind === "function" && edge.from === "#mod_main")); assert(programGraphAuthoringCliNodeAdd.node.children.some((edge) => edge.kind === "body" && edge.to === "#block_add_body")); assert(programGraphAuthoringCliNodeAdd.node.children.some((edge) => edge.kind === "param" && edge.to === "#param_add_x")); assert.equal(programGraphAuthoringCliCleanupPatch.ok, true); assert.equal(programGraphAuthoringCliCleanupPatch.operationCount, 3); assert.match(programGraphAuthoringCliCallsText, /query: fn:main calls:std/); assert.match(programGraphAuthoringCliCallsText, /qualified:std\.args\.parseU32/); assert.match(programGraphAuthoringCliCallsText, /qualified:std\.fmt\.u32/); assert.match(programGraphAuthoringCliCallsText, /resolved:true/); assert.match(programGraphAuthoringCliRefsText, /query: refs:add_u32/); assert.match(programGraphAuthoringCliRefsText, /target:function node:#fn_add_u32/); assert.match(programGraphAuthoringCliRefsText, /fn:main name:add_u32/); assert.equal(programGraphAuthoringCliQuery.ok, true); assert.equal(programGraphAuthoringCliQuery.inputKind, "repository-graph"); assert(programGraphAuthoringCliQuery.functions.some((fun) => fun.name === "main" && fun.public && fun.fallible)); assert(programGraphAuthoringCliQuery.functions.some((fun) => fun.name === "add_u32" && fun.returnType === "u32" && fun.params.length === 2)); assert(!programGraphAuthoringCliQuery.functions.some((fun) => fun.name === "add")); assert(programGraphAuthoringCliQuery.functions.some((fun) => fun.test === "add_u32 works")); assert(!programGraphAuthoringCliQuery.patchOperations.some((op) => op.includes("setMain"))); assert(programGraphAuthoringCliQuery.patchOperations.some((op) => op.startsWith("replaceFunctionBody main\n"))); assert.equal(programGraphAuthoringCliCheck.ok, true); assert.equal(programGraphAuthoringCliCheck.sourceFile, `${programGraphAuthoringCliPackage}/zero.graph`); assert.equal(programGraphAuthoringCliCheck.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphAuthoringCliCheck, "missing"); assert.match(programGraphAuthoringCliGraphBuild.stdout, /program-graph-authoring-cli-graph-build/); assert.match(programGraphAuthoringCliBuild.stdout, /program-graph-authoring-cli-build/); assert.equal(programGraphAuthoringCliTest.ok, true); assert.equal(programGraphAuthoringCliTest.passedTests, 1); assert.equal(programGraphAuthoringCliGraphTest.stdout, "1 test(s) ok\n"); assert.equal(programGraphAuthoringCliRun.stdout, "42\n"); assert.equal(programGraphAuthoringCliGraphRun.stdout, "15\n"); assertSourceGraph(programGraphAuthoringCliSize, `${programGraphAuthoringCliPackage}/zero.graph`, "package:program-graph-authoring-cli@0.1.0", "mapped-final-mir", false, "missing"); assert(programGraphAuthoringCliSize.sizeBreakdown.stdlibHelpers.some((helper) => helper.name === "std.args.parseU32")); assert(programGraphAuthoringCliSize.sizeBreakdown.stdlibHelpers.some((helper) => helper.name === "std.fmt.u32")); assert.equal(programGraphAuthoringCliSync.ok, true); assert.deepEqual(programGraphAuthoringCliSync.changedPaths, [`${programGraphAuthoringCliPackage}/src/main.0`]); assert.match(programGraphAuthoringCliProjectionText, /fn add_u32\(x: u32, y: u32\) -> u32/); assert.match(programGraphAuthoringCliProjectionText, /test "add_u32 works"/); assert.doesNotMatch(programGraphAuthoringCliProjectionText, /fn add\(x: i32, y: i32\) -> i32/); assert.equal(programGraphAuthoringCliStatusAfterHumanEdit.repositoryGraph.projectionState, "source-stale"); assert.equal(programGraphAuthoringCliImport.ok, true); assert.deepEqual(programGraphAuthoringCliImport.changedPaths, [`${programGraphAuthoringCliPackage}/zero.graph`]); assert.equal(programGraphAuthoringCliImport.store.nodes, 96); assert.equal(programGraphAuthoringCliImport.store.sources, 1); assert.equal(programGraphAuthoringCliQueryAfterHumanEdit.ok, true); assert.equal(programGraphAuthoringCliQueryAfterHumanEdit.counts.nodes, 96); assert.deepEqual(programGraphAuthoringCliQueryAfterHumanEdit.modules.map((module) => module.name), ["main"]); assert(programGraphAuthoringCliQueryAfterHumanEdit.calls.some((call) => call.qualifiedName === "std.args.parseU32" && call.targetKind === "stdlib")); assert(programGraphAuthoringCliQueryAfterHumanEdit.calls.some((call) => call.qualifiedName === "std.fmt.u32" && call.targetKind === "stdlib")); assert(!programGraphAuthoringCliQueryAfterHumanEdit.calls.some((call) => call.targetKind === "graphBackedStdlib")); assert.match(programGraphAuthoringCliFindUsageText, /value:usage: zero run \. -- \\n path:/); assert.equal(programGraphAuthoringCliVerifyAfterHumanEdit.ok, true); assert.equal(programGraphAuthoringCliVerifyAfterHumanEdit.repositoryGraph.projectionState, "clean"); assert.equal(programGraphAuthoringCliCheckAfterHumanEdit.ok, true); assert.equal(programGraphAuthoringCliCheckAfterHumanEdit.sourceFile, `${programGraphAuthoringCliPackage}/zero.graph`); assertRepositoryGraphNativeCheck(programGraphAuthoringCliCheckAfterHumanEdit, "clean"); assert.equal(programGraphAuthoringCliTestAfterHumanEdit.ok, true); assert.equal(programGraphAuthoringCliTestAfterHumanEdit.passedTests, 1); assert.equal(programGraphAuthoringCliRunAfterHumanEdit.stdout, "11\n"); assert.equal(programGraphSourceFreeCImportSync.ok, true); assert.equal(programGraphSourceFreeCImportSync.repositoryGraph.projectionValidity, "clean"); assert.equal(programGraphSourceFreeCImportCheck.ok, true); assert.equal(programGraphSourceFreeCImportCheck.graph.sourceProjectionState, "missing"); assertRepositoryGraphNativeCheck(programGraphSourceFreeCImportCheck, "missing"); assert.equal(programGraphSourceFreeCImportRun.stdout, "source-free c import ok\n"); assert.equal(programGraphSourceFreeCImportCwdBuild.sourceFile, resolve(`${programGraphSourceFreeCImportPackage}/zero.graph`)); assert.equal(programGraphSourceFreeCImportCwdBuild.graph.artifact, resolve(`${programGraphSourceFreeCImportPackage}/zero.graph`)); assert.equal(programGraphSourceFreeCImportCwdBuild.graph.sourceProjectionState, "missing"); assert.notEqual(programGraphIdentityMismatchCheck.code, 0); const programGraphIdentityMismatchCheckBody = JSON.parse(programGraphIdentityMismatchCheck.stdout); assert.equal(programGraphIdentityMismatchCheckBody.diagnostics[0].code, "RGP007"); assert.equal(programGraphIdentityMismatchCheckBody.diagnostics[0].expected, "package:program-graph-wrong-package@9.9.9"); assert.equal(programGraphIdentityMismatchCheckBody.diagnostics[0].actual, "package:program-graph-fixture@0.1.0"); assert.notEqual(programGraphIdentityMismatchSize.code, 0); assert.equal(JSON.parse(programGraphIdentityMismatchSize.stdout).diagnostics[0].code, "RGP007"); assert.notEqual(programGraphMissingPackageNameCheck.code, 0); const programGraphMissingPackageNameBody = JSON.parse(programGraphMissingPackageNameCheck.stdout); assert.equal(programGraphMissingPackageNameBody.diagnostics[0].code, "RGP007"); assert.equal(programGraphMissingPackageNameBody.diagnostics[0].message, "repository graph compiler input requires package.name"); assert.match(programGraphMissingPackageNameBody.diagnostics[0].actual, /package:program-graph-fixture@0\.1\.0/); assert.equal(programGraphBadProjectionStatus.repositoryGraph.projectionState, "conflict"); assert.equal(programGraphBadProjectionStatus.repositoryGraph.projectionValidity, "conflict"); assert.equal(programGraphBadProjectionCheck.ok, true); assert.equal(programGraphBadProjectionCheck.graph.sourceProjectionState, "conflict"); assert.notEqual(programGraphBadProjectionSync.code, 0); assert.equal(JSON.parse(programGraphBadProjectionSync.stdout).diagnostics[0].code, "RGP004"); assert.notEqual(programGraphMissingStoreCheck.code, 0); const programGraphMissingStoreBody = JSON.parse(programGraphMissingStoreCheck.stdout); assert.equal(programGraphMissingStoreBody.ok, false); assert.equal(programGraphMissingStoreBody.mode, "compiler-input"); assert.equal(programGraphMissingStoreBody.repositoryGraph.storePresent, false); assert.equal(programGraphMissingStoreBody.diagnostics[0].code, "RGP001"); assert.equal(programGraphMissingStoreBody.diagnostics[0].path, programGraphMissingStorePackage); assert.match(programGraphMissingStoreBody.repairCommands.join("\n"), /zero import/); assert.notEqual(programGraphInvalidStoreCheck.code, 0); const programGraphInvalidStoreBody = JSON.parse(programGraphInvalidStoreCheck.stdout); assert.equal(programGraphInvalidStoreBody.ok, false); assert.equal(programGraphInvalidStoreBody.mode, "compiler-input"); assert.equal(programGraphInvalidStoreBody.repositoryGraph.storePresent, true); assert.equal(programGraphInvalidStoreBody.repositoryGraph.storeValid, false); assert.equal(programGraphInvalidStoreBody.diagnostics[0].code, "RGP003"); assert.equal(programGraphInvalidStoreBody.diagnostics[0].path, programGraphInvalidStorePackage); assert.match(programGraphInvalidStoreBody.repairCommands.join("\n"), /zero import/); assert.equal(programGraphSourceFixtureDriftCheck.ok, true); assert.equal(programGraphSourceFixtureDriftCheck.graph.lowering, "graph-native-check"); assert.equal(programGraphSourceFixtureDriftCheck.graph.sourceProjectionState, "clean"); assertRepositoryGraphNativeCheck(programGraphSourceFixtureDriftCheck, "clean"); assert.equal(programGraphSourceFixtureDriftVerifyAfterRefresh.ok, true); assert.notEqual(programGraphSourceFixtureDriftVerify.code, 0); const programGraphSourceFixtureDriftBody = JSON.parse(programGraphSourceFixtureDriftVerify.stdout); assert.equal(programGraphSourceFixtureDriftBody.ok, false); assert.equal(programGraphSourceFixtureDriftBody.mode, "verify-projection"); assert.equal(programGraphSourceFixtureDriftBody.repositoryGraph.compilerInput, "repository-graph"); assert.equal(programGraphSourceFixtureDriftBody.diagnostics[0].code, "RGP006"); assert.match(programGraphSourceFixtureDriftBody.repairCommands.join("\n"), /zero import/); assert.match(programGraphSourceFixtureDriftBody.repairCommands.join("\n"), /zero export/); assert.equal(programGraphTargetIncompatibleSync.ok, true); assert.notEqual(programGraphTargetIncompatibleCheck.code, 0); const programGraphTargetIncompatibleBody = JSON.parse(programGraphTargetIncompatibleCheck.stdout); assert.equal(programGraphTargetIncompatibleBody.ok, false); assert.equal(programGraphTargetIncompatibleBody.diagnostics[0].code, "PKG004"); assert.match(programGraphTargetIncompatibleBody.diagnostics[0].actual, /target-webbits targets/); assert.equal(programGraphTargetCapabilitySync.ok, true); assert.notEqual(programGraphTargetCapabilityCheck.code, 0); const programGraphTargetCapabilityBody = JSON.parse(programGraphTargetCapabilityCheck.stdout); assert.equal(programGraphTargetCapabilityBody.ok, false); assert.equal(programGraphTargetCapabilityBody.diagnostics[0].code, "TAR002"); assert.match(programGraphTargetCapabilityBody.diagnostics[0].actual, /lacks Fs/); const programGraphBackendMismatchCheck = JSON.parse((await execFileAsync(zero, ["check", "--json", "--backend", "zero-coff-x64", "--target", "linux-musl-x64", programGraphSourceFixturePackage])).stdout); assert.equal(programGraphBackendMismatchCheck.ok, true); assert.equal(programGraphBackendMismatchCheck.targetReadiness.ok, false); assert.equal(programGraphBackendMismatchCheck.targetReadiness.diagnostics[0].code, "BLD004"); assert.equal(programGraphBackendMismatchCheck.targetReadiness.diagnostics[0].backendBlocker.backend, "zero-coff-x64"); const programGraphRepositoryStatus = JSON.parse((await execFileAsync(zero, ["status", "--json", "--target", "linux-musl-x64", programGraphSourceFixturePackage])).stdout); assert.equal(programGraphRepositoryStatus.repositoryGraph.storePresent, true); assert.equal(programGraphRepositoryStatus.repositoryGraph.storeValid, true); assert.equal(programGraphRepositoryStatus.repositoryGraph.projectionState, "clean"); assert.equal(programGraphRepositoryStatus.repositoryGraph.compilerInput, "repository-graph"); const programGraphRepositoryVerify = JSON.parse((await execFileAsync(zero, ["verify-projection", "--json", "--target", "linux-musl-x64", programGraphSourceFixturePackage])).stdout); assert.equal(programGraphRepositoryVerify.ok, true); assert.equal(programGraphRepositoryVerify.writes, false); assert.deepEqual(programGraphDumpJson, programGraphBody); assert.match(programGraphDump, /^zero-graph v1\n/); assert.match(programGraphDump, /origin source-text/); assert.match(programGraphDump, /module "hello"/); assert.match(programGraphDump, /hash "graph:[0-9a-f]{16}"/); assert.doesNotMatch(programGraphDump, /validation "shape-valid" ok/); assert.doesNotMatch(programGraphDump, /idStrategy/); assert.doesNotMatch(programGraphDump, /canonicalSource/); assert.doesNotMatch(programGraphDump, /moduleIdentity/); assert.doesNotMatch(programGraphDump, /graphHash/); assert.doesNotMatch(programGraphDump, /counts nodes=/); assert.doesNotMatch(programGraphDump, /node id=/); assert.match(programGraphDump, /node #mod_[0-9a-f]{8} Module name:"hello"/); assert.match(programGraphDump, /edge #mod_[0-9a-f]{8} function #decl_[0-9a-f]{8} order:0/); assert.match(programGraphView, /^pub fn main\(world: World\) -> Void raises \{\n/); assert.match(programGraphView, /check world\.out\.write\("hello from zero\\n"\)/); assert.match(programGraphRichView, /bytesTail\(bytesSpan\)\[1\]/); assert.match(programGraphRichView, /numbers\[2\.\.\]/); assert.match(programGraphCharView, /again == 'A'/); assert.match(programGraphBody.graphHash, /^graph:[0-9a-f]{16}$/); assert.equal(programGraphBody.validation.ok, true); assert.equal(programGraphBody.validation.state, "shape-valid"); assert(programGraphBody.counts.nodes > 0); assert(programGraphBody.counts.edges > 0); assert(programGraphBody.nodes.every((item) => /^#[a-z][a-z0-9]*_[0-9a-f]{8}(-[0-9a-f]{4}(-[0-9]+)?)?$/.test(item.id) && /^nodehash:[0-9a-f]{16}$/.test(item.nodeHash))); assert(programGraphBody.edges.every((item) => item.target === "node")); assert(programGraphBody.nodes.some((item) => item.kind === "Module" && item.name === "hello" && item.symbolId === "symbol:hello::module")); assert(programGraphBody.nodes.some((item) => item.kind === "Function" && item.name === "main" && item.public === true && item.fallible === true && item.symbolId === "symbol:hello::value.main" && /^type:[0-9a-f]{16}$/.test(item.typeId))); assert(programGraphBody.nodes.some((item) => item.kind === "Param" && item.name === "world" && item.type === "World" && item.symbolId === "symbol:hello::value.main/param.world")); assert(programGraphBody.nodes.some((item) => item.kind === "EffectRef" && item.name === "error" && /^effect:[0-9a-f]{16}$/.test(item.effectId))); assert(programGraphBody.nodes.some((item) => item.kind === "Check")); assert(programGraphBody.nodes.some((item) => item.kind === "MethodCall")); assert(programGraphBody.edges.some((item) => item.kind === "body")); const programGraphWrongSchemaPath = `${outDir}/wrong-schema.program-graph`; await writeFile(programGraphWrongSchemaPath, "zero-graph v2\n"); const programGraphWrongSchema = await execFileAsync(zero, ["validate", "--json", programGraphWrongSchemaPath]).catch((error) => error); assert(programGraphWrongSchema.code); assert.equal(JSON.parse(programGraphWrongSchema.stdout).diagnostics[0].message, "unknown program graph schema version"); const programGraphFailedArtifactPath = `${outDir}/failed-validation.program-graph`; await writeFile(programGraphFailedArtifactPath, [ "zero-graph v1", "origin source-text", "module \"main\"", "hash \"\"", "validation \"decoded\" failed", "diagnostic code:\"GRF001\" message:\"program graph construction failed\"", "", ].join("\n")); const programGraphFailedArtifact = await execFileAsync(zero, ["validate", "--json", programGraphFailedArtifactPath]).catch((error) => error); assert(programGraphFailedArtifact.code); assert.equal(JSON.parse(programGraphFailedArtifact.stdout).diagnostics[0].message, "program graph input reports failed validation"); const programGraphTrailingArtifactPath = `${outDir}/trailing-content.program-graph`; await writeFile(programGraphTrailingArtifactPath, `${programGraphDump}\nextra\n`); const programGraphTrailingArtifact = await execFileAsync(zero, ["validate", "--json", programGraphTrailingArtifactPath]).catch((error) => error); assert(programGraphTrailingArtifact.code); assert.equal(JSON.parse(programGraphTrailingArtifact.stdout).diagnostics[0].message, "unexpected content after graph header"); assert(programGraphBody.edges.some((item) => item.kind === "statement" && item.order === 0)); const programGraphDuplicateIdFixture = `${outDir}/program-graph-duplicate-id-stress.0`; const programGraphDuplicateIdPath = `${outDir}/program-graph-duplicate-id-stress.program-graph`; await writeFile(programGraphDuplicateIdFixture, [ "pub fn main() -> Void {", ...Array.from({ length: 700 }, (_, index) => ` let x${index}: i32 = 1`), "}", "", ].join("\n")); const programGraphDuplicateIdDump = await execFileAsync(zero, ["import", "--format", "text", "--out", programGraphDuplicateIdPath, programGraphDuplicateIdFixture]); assert.equal(programGraphDuplicateIdDump.stdout, ""); assert.equal((await execFileAsync(zero, ["validate", programGraphDuplicateIdPath])).stdout, "program graph ok\n"); const programGraphDuplicateIdText = await readFile(programGraphDuplicateIdPath, "utf8"); const programGraphDuplicateIds = [...programGraphDuplicateIdText.matchAll(/^node (#[^ ]+)/gm)].map((match) => match[1]); assert.equal(new Set(programGraphDuplicateIds).size, programGraphDuplicateIds.length); assert(programGraphDuplicateIds.some((id) => /^#[a-z][a-z0-9]*_[0-9a-f]{8}-[0-9a-f]{4}(-[0-9]+)?$/.test(id))); const programGraphControlFixture = `${outDir}/program-graph-control.0`; const programGraphControlPath = await writeGraphFixture(programGraphControlFixture, "pub fn main(world: World) -> Void raises {\n check world.out.write(\"\\x01 ok\\n\")\n}\n"); const programGraphControl = JSON.parse((await execFileAsync(zero, ["inspect", "--json", programGraphControlPath])).stdout).programGraph; assert(programGraphControl.nodes.some((item) => item.kind === "Literal" && item.value === "\u0001 ok\n")); const programGraphMatchRanges = JSON.parse((await execFileAsync(zero, ["inspect", "--json", "conformance/native/pass/match-scalar-guards.0"])).stdout).programGraph; const programGraphRangeArm = programGraphMatchRanges.nodes.find((item) => item.kind === "MatchArm" && item.name === "1"); assert(programGraphRangeArm); const programGraphRangeEdge = programGraphMatchRanges.edges.find((item) => item.from === programGraphRangeArm.id && item.kind === "rangeEnd"); assert(programGraphRangeEdge); assert(programGraphMatchRanges.nodes.some((item) => item.id === programGraphRangeEdge.to && item.kind === "Literal" && item.value === "3")); const programGraphShapeDefaults = JSON.parse((await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/shape-field-defaults.0"])).stdout).programGraph; const programGraphDefaultField = programGraphShapeDefaults.nodes.find((item) => item.kind === "Field" && item.name === "left"); assert(programGraphDefaultField); const programGraphDefaultEdge = programGraphShapeDefaults.edges.find((item) => item.from === programGraphDefaultField.id && item.kind === "default"); assert(programGraphDefaultEdge); assert(programGraphShapeDefaults.nodes.some((item) => item.id === programGraphDefaultEdge.to && item.kind === "Literal" && item.value === "1")); const memorySize = await execFileAsync(zero, ["size", "--json", "--target", "linux-musl-x64", "examples/memory-package"]); const memorySizeBody = JSON.parse(memorySize.stdout); assert.equal(memorySizeBody.target, "linux-musl-x64"); assert.equal(memorySizeBody.targetSupport.fsAvailable, true); assert(memorySizeBody.requiresCapabilities.includes("memory")); assert(!memorySizeBody.requiresCapabilities.includes("fs")); assert.equal(memorySizeBody.generatedCBytes, 0); assert.equal(memorySizeBody.cBridgeFallback, false); assert(memorySizeBody.loweredIrBytes > 0); assert(memorySizeBody.sections.some((section) => section.name === "direct-size-metadata" && section.kind === "metadata")); assert(memorySizeBody.objectBackend.objectEmission.path.includes("direct-")); assert.equal(memorySizeBody.objectBackend.emitKind, "size"); assert(memorySizeBody.stdlibHelpers.some((helper) => helper.name === "std.mem.copy")); assert(memorySizeBody.stdlibHelperAttribution.some((helper) => helper.name === "std.mem.copy" && helper.estimatedDirectBytes > 0)); assert(memorySizeBody.usedStdlibHelpers.every((helper) => helper.module && helper.effects?.length && helper.errorBehavior && helper.ownershipNotes && helper.example)); assert(memorySizeBody.runtimeShims.some((shim) => shim.name === "stdio-world" && shim.payAsUsed === true)); const genericPairSize = await execFileAsync(zero, ["size", "--json", "examples/generic-pair.0"]); const genericPairSizeBody = JSON.parse(genericPairSize.stdout); assert.equal(genericPairSizeBody.graph.artifact, "examples/generic-pair.graph"); assert.equal(genericPairSizeBody.graph.lowering, "mapped-final-mir"); assert.equal(genericPairSizeBody.cBridgeFallback, false); assert(genericPairSizeBody.loweredIrBytes > 0); const genericInferredSize = await execFileAsync(zero, ["size", "--json", "conformance/native/pass/generic-inferred-specialized-call.0"]); const genericInferredSizeBody = JSON.parse(genericInferredSize.stdout); assert.equal(genericInferredSizeBody.graph.artifact, "conformance/native/pass/generic-inferred-specialized-call.graph"); assert.equal(genericInferredSizeBody.graph.lowering, "mapped-final-mir"); assert.equal(genericInferredSizeBody.cBridgeFallback, false); assert(genericInferredSizeBody.loweredIrBytes > 0); const genericStaticForwardedSize = await execFileAsync(zero, ["size", "--json", "conformance/native/pass/generic-static-forwarded-array-specialization.0"]); const genericStaticForwardedSizeBody = JSON.parse(genericStaticForwardedSize.stdout); assert.equal(genericStaticForwardedSizeBody.graph.artifact, "conformance/native/pass/generic-static-forwarded-array-specialization.graph"); assert.equal(genericStaticForwardedSizeBody.graph.lowering, "mapped-final-mir"); assert.equal(genericStaticForwardedSizeBody.cBridgeFallback, false); assert(genericStaticForwardedSizeBody.loweredIrBytes > 0); const targetsJson = await execFileAsync(zero, ["targets"]); const targetsBody = JSON.parse(targetsJson.stdout); const linuxMuslTarget = targetsBody.targets.find((item) => item.name === "linux-musl-x64"); const windowsMsvcTarget = targetsBody.targets.find((item) => item.aliases.includes("x86_64-windows-msvc")); const linuxGnuTarget = targetsBody.targets.find((item) => item.name === "linux-x64"); const darwinArm64Target = targetsBody.targets.find((item) => item.name === "darwin-arm64"); const darwinX64Target = targetsBody.targets.find((item) => item.name === "darwin-x64"); const linuxArm64Target = targetsBody.targets.find((item) => item.name === "linux-arm64"); assert(linuxMuslTarget.capabilityFacts.some((item) => item.name === "fs" && item.available === true)); assert.equal(linuxMuslTarget.abi, "musl"); assert.equal(linuxMuslTarget.objectFormat, "elf"); assert.equal(linuxMuslTarget.toolchain.crossCompiler, "target-capable C compiler"); assert.equal(linuxMuslTarget.libcFacts.mode, "bundled-libc"); assert.equal(linuxMuslTarget.directBackend.status, "native-exe"); assert.equal(linuxMuslTarget.directBackend.objectSupported, true); assert.equal(linuxMuslTarget.directBackend.exeSupported, true); assert.equal(linuxMuslTarget.directBackend.objectEmitter, "zero-elf64"); assert.equal(linuxMuslTarget.directBackend.exeEmitter, "zero-elf64-exe"); assert.equal(linuxMuslTarget.directBackend.explicitDirectFallback, "never-c-bridge"); assert.equal(linuxMuslTarget.httpRuntime.status, "unsupported"); assert.equal(linuxMuslTarget.httpRuntime.provider, null); assert.match(linuxMuslTarget.httpRuntime.reason, /lacks net/i); assert.equal(windowsMsvcTarget.objectFormat, "coff"); assert.equal(windowsMsvcTarget.libcFacts.mode, "sysroot"); assert.equal(windowsMsvcTarget.libcFacts.sysrootStatus, "missing"); assert.equal(windowsMsvcTarget.directBackend.objectSupported, true); assert.equal(windowsMsvcTarget.directBackend.exeSupported, true); assert.equal(windowsMsvcTarget.directBackend.objectEmitter, "zero-coff-x64"); assert.equal(windowsMsvcTarget.directBackend.exeEmitter, "zero-coff-x64-exe"); assert.equal(linuxGnuTarget.directBackend.objectEmitter, "zero-elf64"); assert.equal(darwinArm64Target.directBackend.objectEmitter, "zero-macho64"); assert.equal(darwinArm64Target.directBackend.exeSupported, true); assert.equal(darwinArm64Target.directBackend.exeEmitter, "zero-macho64-exe"); assert.equal(darwinX64Target.directBackend.objectEmitter, "zero-macho-x64"); assert.equal(darwinX64Target.directBackend.exeSupported, true); assert.equal(darwinX64Target.directBackend.exeEmitter, "zero-macho-x64-exe"); assert.equal(darwinArm64Target.httpRuntime.provider, targetsBody.host === "darwin-arm64" ? "curl" : null); assert.equal(darwinArm64Target.httpRuntime.tlsVerification, targetsBody.host === "darwin-arm64"); if (targetsBody.host === "darwin-arm64") { assert.equal(darwinArm64Target.httpRuntime.customCa.env, "ZERO_HTTP_TEST_CA_BUNDLE"); } assert.equal(linuxArm64Target.directBackend.status, "native-exe"); assert.equal(linuxArm64Target.directBackend.objectEmitter, "zero-elf-aarch64"); assert.equal(linuxArm64Target.directBackend.exeEmitter, "zero-elf-aarch64-exe"); assert.match(linuxArm64Target.directBackend.reason, /direct object and executable backend available/); const zlsSelfTest = await execFileAsync("node", [ "--experimental-strip-types", "--disable-warning=ExperimentalWarning", "scripts/zls.mts", "--self-test", ]); assert.match(zlsSelfTest.stdout, /zls self-test ok/); const cHeaderGraph = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/c-header-import.0"]); const cHeaderGraphBody = JSON.parse(cHeaderGraph.stdout); assert(cHeaderGraphBody.cImports.some((item) => item.header === "conformance/c/simple.h" && item.imports.functions >= 1 && item.cacheKey)); const simpleHeaderImport = cHeaderGraphBody.cImports.find((item) => item.header === "conformance/c/simple.h"); assert(simpleHeaderImport.typedModel.functions.some((item) => item.name === "zero_c_add" && item.params.length === 2)); assert(simpleHeaderImport.typedModel.constants.some((item) => item.name === "ZERO_C_ANSWER" && item.value === "42")); assert(simpleHeaderImport.typedModel.structs.some((item) => item.name === "zero_c_point" && item.fields.some((field) => field.name === "y"))); assert(simpleHeaderImport.typedModel.enums.some((item) => item.name === "zero_c_color" && item.cases.some((entry) => entry.name === "ZERO_C_BLUE"))); assert(simpleHeaderImport.typedModel.typedefs.some((item) => item.name === "zero_c_int" && item.target === "int")); assert.equal(typeof simpleHeaderImport.cache.target, "string"); const cImportTargetLinux = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "--target", "linux-musl-x64", "conformance/check/pass/c-import-target-linux.0"]); const cImportTargetLinuxBody = JSON.parse(cImportTargetLinux.stdout); assert.equal(cImportTargetLinuxBody.ok, true); assert.equal(cImportTargetLinuxBody.targetReadiness.ok, true); assert.equal(cImportTargetLinuxBody.targetReadiness.buildable, true); const cImportTargetWin = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "--target", "win32-x64.exe", "conformance/check/pass/c-import-target-win.0"]); const cImportTargetWinBody = JSON.parse(cImportTargetWin.stdout); assert.equal(cImportTargetWinBody.ok, true); assert.equal(cImportTargetWinBody.targetReadiness.ok, true); assert.equal(cImportTargetWinBody.targetReadiness.buildable, true); const cImportTargetLinuxGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "linux-musl-x64", "conformance/check/pass/c-import-target-linux.0"]); const cImportTargetLinuxModel = JSON.parse(cImportTargetLinuxGraph.stdout).cImports.find((item) => item.header === "conformance/c/target-conditional.h").typedModel; assert(cImportTargetLinuxModel.functions.some((item) => item.name === "zero_c_linux_add")); assert(cImportTargetLinuxModel.functions.some((item) => item.name === "zero_c_not_windows")); assert(!cImportTargetLinuxModel.functions.some((item) => item.name === "zero_c_windows_add")); const cImportTargetWinGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "win32-x64.exe", "conformance/check/pass/c-import-target-win.0"]); const cImportTargetWinModel = JSON.parse(cImportTargetWinGraph.stdout).cImports.find((item) => item.header === "conformance/c/target-conditional.h").typedModel; assert(cImportTargetWinModel.functions.some((item) => item.name === "zero_c_windows_add")); assert(!cImportTargetWinModel.functions.some((item) => item.name === "zero_c_linux_add")); assert(!cImportTargetWinModel.functions.some((item) => item.name === "zero_c_not_windows")); const cImportTypeShadowReadiness = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "conformance/native/pass/c-import-type-shadowing.0"]); const cImportTypeShadowReadinessBody = JSON.parse(cImportTypeShadowReadiness.stdout); assert.equal(cImportTypeShadowReadinessBody.ok, true); assert.equal(cImportTypeShadowReadinessBody.targetReadiness.buildable, false); assert.equal(cImportTypeShadowReadinessBody.targetReadiness.diagnostics[0].backendBlocker.unsupportedFeature, "ref"); const cImportLaterLocalReadiness = await execFileAsync(zero, ["check", "--json", "--emit", "obj", "conformance/native/pass/c-import-alias-later-local.0"]); const cImportLaterLocalReadinessBody = JSON.parse(cImportLaterLocalReadiness.stdout); assert.equal(cImportLaterLocalReadinessBody.ok, true); assert.equal(cImportLaterLocalReadinessBody.targetReadiness.ok, true); assert.equal(cImportLaterLocalReadinessBody.targetReadiness.buildable, true); assert.equal(cImportLaterLocalReadinessBody.targetReadiness.diagnostics.length, 0); const cImportMissingLinkReadiness = await execFileAsync(zero, ["check", "--json", "conformance/native/pass/c-import-alias-later-local.0"]); const cImportMissingLinkReadinessBody = JSON.parse(cImportMissingLinkReadiness.stdout); assert.equal(cImportMissingLinkReadinessBody.ok, true); assert.equal(cImportMissingLinkReadinessBody.targetReadiness.ok, false); assert.equal(cImportMissingLinkReadinessBody.targetReadiness.buildable, false); assert.equal(cImportMissingLinkReadinessBody.targetReadiness.diagnostics[0].code, "CIMP005"); const cImportMissingLinkBuild = await execFileAsync(zero, ["build", "--json", "conformance/native/pass/c-import-alias-later-local.0", "--out", `.zero/out/c-import-missing-link-${process.pid}`]).catch((error) => error); assert.notEqual(cImportMissingLinkBuild.code, 0); assert.equal(JSON.parse(cImportMissingLinkBuild.stdout).diagnostics[0].code, "CIMP005"); const cImportPartialLinkRoot = `/tmp/zero-c-import-partial-link-${process.pid}`; await rm(cImportPartialLinkRoot, { recursive: true, force: true }); await mkdir(`${cImportPartialLinkRoot}/src`, { recursive: true }); await mkdir(`${cImportPartialLinkRoot}/vendor/include`, { recursive: true }); await writeFile(`${cImportPartialLinkRoot}/vendor/include/a.h`, "int zero_a_add(int left, int right);\n"); await writeFile(`${cImportPartialLinkRoot}/vendor/include/b.h`, "int zero_b_add(int left, int right);\n"); await writeZeroToml(cImportPartialLinkRoot, { package: { name: "c-import-partial-link", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { a: { headers: ["vendor/include/a.h"], include: ["vendor/include"], lib: ["vendor/lib/a.o"], link: [], mode: "static" }, b: { headers: ["vendor/include/b.h"], include: ["vendor/include"], lib: [], link: [], mode: "static" } } } }); await writeFile(`${cImportPartialLinkRoot}/src/main.0`, `extern c "vendor/include/a.h" as a extern c "vendor/include/b.h" as b export c fn main() -> i32 { return a.zero_a_add(1, 2) + b.zero_b_add(3, 4) } `); await importPackageGraph(cImportPartialLinkRoot); const cImportPartialLinkReadiness = await execFileAsync(zero, ["check", "--json", cImportPartialLinkRoot]); const cImportPartialLinkReadinessBody = JSON.parse(cImportPartialLinkReadiness.stdout); assert.equal(cImportPartialLinkReadinessBody.ok, true); assert.equal(cImportPartialLinkReadinessBody.targetReadiness.ok, false); assert.equal(cImportPartialLinkReadinessBody.targetReadiness.buildable, false); assert.equal(cImportPartialLinkReadinessBody.targetReadiness.diagnostics[0].code, "CIMP005"); assert.match(cImportPartialLinkReadinessBody.targetReadiness.diagnostics[0].actual, /b\.h/); const cImportPartialLinkBuild = await execFileAsync(zero, ["build", "--json", cImportPartialLinkRoot, "--out", `${cImportPartialLinkRoot}/partial-link`]).catch((error) => error); assert.notEqual(cImportPartialLinkBuild.code, 0); const cImportPartialLinkBuildBody = JSON.parse(cImportPartialLinkBuild.stdout); assert.equal(cImportPartialLinkBuildBody.diagnostics[0].code, "CIMP005"); assert.match(cImportPartialLinkBuildBody.diagnostics[0].actual, /b\.h/); await rm(cImportPartialLinkRoot, { recursive: true, force: true }); const externCallRoot = `/tmp/zero-extern-c-call-${process.pid}`; const externCallShadowRoot = `/tmp/zero-extern-c-shadow-${process.pid}`; const externCallScalarRoot = `/tmp/zero-extern-c-scalar-${process.pid}`; await rm(externCallRoot, { recursive: true, force: true }); await rm(externCallShadowRoot, { recursive: true, force: true }); await rm(externCallScalarRoot, { recursive: true, force: true }); await mkdir(`${externCallRoot}/src`, { recursive: true }); await mkdir(`${externCallRoot}/vendor/include`, { recursive: true }); await mkdir(`${externCallRoot}/vendor/lib`, { recursive: true }); await mkdir(`${externCallShadowRoot}/vendor/include`, { recursive: true }); await mkdir(`${externCallScalarRoot}/src`, { recursive: true }); const externCallObjectRel = "vendor/lib/zero ext's.o"; const externCallDirtyObjectRel = "vendor/lib/zero_ext_dirty.o"; const externCallSymbolPrefix = process.platform === "darwin" ? "_" : ""; let externCallDirtyAsm = ""; if (process.arch === "x64") { externCallDirtyAsm = `.text .globl ${externCallSymbolPrefix}zero_ext_dirty_u8 ${externCallSymbolPrefix}zero_ext_dirty_u8: movq $257, %rax ret `; } else if (process.arch === "arm64") { externCallDirtyAsm = `.text .globl ${externCallSymbolPrefix}zero_ext_dirty_u8 ${externCallSymbolPrefix}zero_ext_dirty_u8: movz x0, #257 ret `; } await writeFile(`${externCallRoot}/vendor/include/zero_ext.h`, `#ifdef __cplusplus extern "C" { #endif int zero_ext_add( int left, int right ); // int zero_ext_commented(int value); /* int zero_ext_block_commented(int value); */ #if 0 int zero_ext_disabled(int value); #endif int zero_ext_inline_left(int value); int zero_ext_inline_right(int value); unsigned char zero_ext_dirty_u8(void); #ifdef __cplusplus } #endif `); await writeFile(`${externCallShadowRoot}/vendor/include/zero_ext.h`, "int zero_ext_wrong(int, int);\n"); await writeFile(`${externCallRoot}/vendor/lib/zero_ext.c`, '#include "zero_ext.h"\nint zero_ext_add(int a, int b) { return a + b; }\nint zero_ext_inline_left(int value) { return value + 1; }\nint zero_ext_inline_right(int value) { return value + 2; }\n'); await execFileAsync("cc", ["-I", `${externCallRoot}/vendor/include`, "-c", `${externCallRoot}/vendor/lib/zero_ext.c`, "-o", `${externCallRoot}/${externCallObjectRel}`]); if (externCallDirtyAsm) { await writeFile(`${externCallRoot}/vendor/lib/zero_ext_dirty.S`, externCallDirtyAsm); await execFileAsync("cc", ["-c", `${externCallRoot}/vendor/lib/zero_ext_dirty.S`, "-o", `${externCallRoot}/${externCallDirtyObjectRel}`]); } await writeZeroToml(externCallRoot, { package: { name: "extern-c-call", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { ext: { headers: ["vendor/include/zero_ext.h"], include: ["vendor/include"], lib: [externCallObjectRel, ...(externCallDirtyAsm ? [externCallDirtyObjectRel] : [])], link: [], mode: "static" }, unused: { headers: ["vendor/include/unused.h"], include: ["vendor/include"], lib: ["vendor/lib/missing-unused.o"], link: [], mode: "static" } } } }); await writeZeroToml(externCallScalarRoot, { package: { name: "extern-c-scalar", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { ext: { headers: [`${externCallRoot}/vendor/include/zero_ext.h`], include: [`${externCallRoot}/vendor/include`], lib: [`${externCallRoot}/${externCallObjectRel}`], link: [], mode: "static" } } } }); await writeFile(`${externCallRoot}/src/main.0`, `extern c "vendor/include/zero_ext.h" as c pub fn main(world: World) -> Void raises { let total: i32 = c.zero_ext_add(20, 20) + c.zero_ext_inline_right(0) if total == 42${externCallDirtyAsm ? " && c.zero_ext_dirty_u8() == 1_u8" : ""} { check world.out.write("extern c call ok\\n") } else { check world.out.write("extern c call failed\\n") } } `); await writeFile(`${externCallRoot}/src/disabled.0`, `extern c "vendor/include/zero_ext.h" as c pub fn main() -> i32 { return c.zero_ext_disabled(1) } `); await writeFile(`${externCallRoot}/src/commented.0`, `extern c "vendor/include/zero_ext.h" as c pub fn main() -> i32 { return c.zero_ext_commented(1) } `); await writeFile(`${externCallScalarRoot}/src/main.0`, `extern c "${externCallRoot}/vendor/include/zero_ext.h" as c export c fn main() -> i32 { return c.zero_ext_add(20, 22) } `); await importPackageGraph(externCallRoot); await importPackageGraph(externCallScalarRoot); const externCallShadowCheck = await execFileAsync(zero, ["check", "--json", externCallRoot], { cwd: externCallShadowRoot }); const externCallShadowCheckBody = JSON.parse(externCallShadowCheck.stdout); assert.equal(externCallShadowCheckBody.ok, true); const externCallDisabledCheck = await execFileAsync(zero, ["import", "--json", "--format", "binary", "--out", "src/disabled.graph", "src/disabled.0"], { cwd: externCallRoot }).catch((error) => error); assert.notEqual(externCallDisabledCheck.code, 0); const externCallDisabledCheckBody = JSON.parse(externCallDisabledCheck.stdout); assert.equal(externCallDisabledCheckBody.diagnostics[0].code, "CIMP004"); const externCallCommentedCheck = await execFileAsync(zero, ["import", "--json", "--format", "binary", "--out", "src/commented.graph", "src/commented.0"], { cwd: externCallRoot }).catch((error) => error); assert.notEqual(externCallCommentedCheck.code, 0); const externCallCommentedCheckBody = JSON.parse(externCallCommentedCheck.stdout); assert.equal(externCallCommentedCheckBody.diagnostics[0].code, "CIMP004"); assert.match(externCallCommentedCheckBody.diagnostics[0].message, /not declared/); const externCallScalarCrossReadiness = await execFileAsync(zero, ["check", "--json", "--target", "linux-musl-arm64", externCallScalarRoot]); const externCallScalarCrossReadinessBody = JSON.parse(externCallScalarCrossReadiness.stdout); assert.equal(externCallScalarCrossReadinessBody.ok, true); assert.equal(externCallScalarCrossReadinessBody.targetReadiness.ok, true); assert.equal(externCallScalarCrossReadinessBody.targetReadiness.buildable, true); assert.equal(externCallScalarCrossReadinessBody.targetReadiness.diagnostics.length, 0); const externCallGraph = await execFileAsync(zero, ["inspect", "--json", externCallRoot]); const externCallGraphBody = JSON.parse(externCallGraph.stdout); const externCallImport = externCallGraphBody.cImports.find((item) => item.header === "vendor/include/zero_ext.h"); assert(externCallImport); assert.equal(externCallImport.alias, "c"); assert.match(externCallImport.cache.headerHash, /^[0-9a-f]{16}$/); assert(Array.isArray(externCallImport.typedModel.functions)); assert(!externCallImport.typedModel.functions.some((item) => item.name === "zero_ext_commented")); assert(!externCallImport.typedModel.functions.some((item) => item.name === "zero_ext_block_commented")); assert(!externCallImport.typedModel.functions.some((item) => item.name === "zero_ext_disabled")); const externCallGraphSizeArtifact = `${externCallRoot}/extern-call-size-metadata.json`; const externCallGraphSize = await execFileAsync(zero, ["size", "--json", "--out", externCallGraphSizeArtifact, externCallRoot]); assert.equal(JSON.parse(externCallGraphSize.stdout).graph.moduleIdentity, "package:extern-c-call@0.1.0"); const externCallBuildOut = `${externCallRoot}/extern-call`; const externCallBuild = await execFileAsync(zero, ["build", "--json", externCallRoot, "--out", externCallBuildOut]); const externCallBuildBody = JSON.parse(externCallBuild.stdout); assert.equal(externCallBuildBody.emit, "exe"); assert.notEqual(externCallBuildBody.objectBackend.objectEmission.path, "none"); assert.notEqual(externCallBuildBody.objectBackend.linking.externalToolchain, "none"); assert.match(externCallBuildBody.objectBackend.linking.targetLibraries, /zero-runtime/); assert.match(externCallBuildBody.objectBackend.linking.targetLibraries, /c-imports/); assert(externCallBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item.endsWith(externCallObjectRel))); if (externCallDirtyAsm) assert(externCallBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item.endsWith(externCallDirtyObjectRel))); assert(!externCallBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item.endsWith("vendor/lib/missing-unused.o"))); const externCallObjectOverhead = externCallBuildBody.objectBackend.linking.objectFormat === "coff" ? (externCallBuildBody.objectBackend.objectEmission.dataSections ? 2 : 1) : (externCallBuildBody.objectBackend.objectEmission.dataSections ? 1 : 0); const externCallExpectedExternalSymbols = externCallDirtyAsm ? 3 : 2; assert.equal( externCallBuildBody.objectBackend.objectEmission.symbolCount, externCallBuildBody.objectBackend.directFacts.functionCount + externCallBuildBody.objectBackend.directFacts.runtimeHelperCount + externCallExpectedExternalSymbols + externCallObjectOverhead ); assert.equal(externCallBuildBody.releaseTargetContract.selectedEmitter, externCallBuildBody.releaseTargetContract.directObjectEmitter); assert.equal(externCallBuildBody.releaseTargetContract.libc.artifactMode, externCallBuildBody.releaseTargetContract.libc.targetMode); const externCallRun = await execFileAsync(zero, ["run", externCallRoot]); assert.equal(externCallRun.stdout, "extern c call ok\n"); const externCallScalarBuildOut = `${externCallScalarRoot}/extern-scalar`; const externCallScalarBuild = await execFileAsync(zero, ["build", "--json", externCallScalarRoot, "--out", externCallScalarBuildOut]); const externCallScalarBuildBody = JSON.parse(externCallScalarBuild.stdout); assert.equal(externCallScalarBuildBody.emit, "exe"); assert.match(externCallScalarBuildBody.objectBackend.linking.targetLibraries, /c-imports/); assert.doesNotMatch(externCallScalarBuildBody.objectBackend.linking.targetLibraries, /zero-runtime/); assert.notEqual(externCallScalarBuildBody.objectBackend.linking.externalToolchain, "none"); assert(!externCallScalarBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item === "zero_runtime.o")); assert(externCallScalarBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item.endsWith(externCallObjectRel))); assert.equal(externCallScalarBuildBody.releaseTargetContract.selectedEmitter, externCallScalarBuildBody.releaseTargetContract.directObjectEmitter); assert.equal(externCallScalarBuildBody.releaseTargetContract.libc.artifactMode, externCallScalarBuildBody.releaseTargetContract.libc.targetMode); await rm(externCallRoot, { recursive: true, force: true }); await rm(externCallShadowRoot, { recursive: true, force: true }); await rm(externCallScalarRoot, { recursive: true, force: true }); const unsafeExternLinkRoot = `/tmp/zero-extern-c-unsafe-link-${process.pid}`; await rm(unsafeExternLinkRoot, { recursive: true, force: true }); await mkdir(`${unsafeExternLinkRoot}/src`, { recursive: true }); await mkdir(`${unsafeExternLinkRoot}/vendor/include`, { recursive: true }); await writeFile(`${unsafeExternLinkRoot}/vendor/include/zero_ext.h`, "int zero_ext_add(int left, int right);\n"); await writeZeroToml(unsafeExternLinkRoot, { package: { name: "extern-c-unsafe-link", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { ext: { headers: ["vendor/include/zero_ext.h"], include: ["vendor/include"], lib: [], link: ["zero_ext;touch"], mode: "static" } } } }); await writeFile(`${unsafeExternLinkRoot}/src/main.0`, `extern c "vendor/include/zero_ext.h" as c pub fn main() -> i32 { return c.zero_ext_add(20, 22) } `); await importPackageGraph(unsafeExternLinkRoot); const unsafeExternLinkReadiness = await execFileAsync(zero, ["check", "--json", unsafeExternLinkRoot]); const unsafeExternLinkReadinessBody = JSON.parse(unsafeExternLinkReadiness.stdout); assert.equal(unsafeExternLinkReadinessBody.ok, true); assert.equal(unsafeExternLinkReadinessBody.targetReadiness.buildable, false); assert.equal(unsafeExternLinkReadinessBody.targetReadiness.diagnostics[0].code, "CIMP005"); assert.match(unsafeExternLinkReadinessBody.targetReadiness.diagnostics[0].actual, /unsafe library name/); const unsafeExternLinkBuild = await execFileAsync(zero, ["build", "--json", unsafeExternLinkRoot, "--out", `${unsafeExternLinkRoot}/extern-link`]).catch((error) => error); assert.notEqual(unsafeExternLinkBuild.code, 0); assert.equal(JSON.parse(unsafeExternLinkBuild.stdout).diagnostics[0].code, "CIMP005"); await rm(unsafeExternLinkRoot, { recursive: true, force: true }); const runtimeManifestRoot = `/tmp/zero-runtime-manifest-link-${process.pid}`; await rm(runtimeManifestRoot, { recursive: true, force: true }); await mkdir(`${runtimeManifestRoot}/src`, { recursive: true }); await writeZeroToml(runtimeManifestRoot, { package: { name: "runtime-manifest-link", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, c: { libs: { unused: { headers: ["vendor/include/unused.h"], include: ["vendor/include"], lib: ["vendor/lib/missing.o"], link: ["zero_missing_system"], mode: "static" } } } }); await writeFile(`${runtimeManifestRoot}/src/main.0`, `pub fn main(world: World) -> Void raises { check world.out.write("runtime manifest ignored\\n") } `); await importPackageGraph(runtimeManifestRoot); const runtimeManifestBuildOut = `${runtimeManifestRoot}/runtime-manifest`; const runtimeManifestBuild = await execFileAsync(zero, ["build", "--json", runtimeManifestRoot, "--out", runtimeManifestBuildOut]); const runtimeManifestBuildBody = JSON.parse(runtimeManifestBuild.stdout); assert(!runtimeManifestBuildBody.objectBackend.linkerPlan.staticLibraries.some((item) => item.endsWith("vendor/lib/missing.o"))); assert(!runtimeManifestBuildBody.objectBackend.linkerPlan.systemLibraries.includes("zero_missing_system")); const runtimeManifestRun = await execFileAsync(zero, ["run", runtimeManifestRoot]); assert.equal(runtimeManifestRun.stdout, "runtime manifest ignored\n"); await rm(runtimeManifestRoot, { recursive: true, force: true }); const cInteropGraph = await execFileAsync(zero, ["inspect", "--json", "examples/c-interop"]); const cInteropGraphBody = JSON.parse(cInteropGraph.stdout); const mathLib = cInteropGraphBody.cLibraries.find((item) => item.name === "math"); assert(mathLib); assert.equal(mathLib.linkMode, "static"); assert.equal(mathLib.targetValidation.vendoredLibraries, true); assert.equal(mathLib.targetValidation.vendoredHeaders, true); assert.equal(mathLib.targetValidation.pkgConfigTargetSafe, true); const cInteropCrossGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "linux-musl-x64", "examples/c-interop"]); const cInteropCrossGraphBody = JSON.parse(cInteropCrossGraph.stdout); assert.equal(cInteropCrossGraphBody.cLibraries[0].targetValidation.pkgConfigTargetSafe, true); assert.equal(cInteropCrossGraphBody.cLibraries[0].targetValidation.implicitHostDiscovery, false); assert.equal(cInteropCrossGraphBody.cLibraries[0].linkPlan.hostDiscovery, "none"); const hostLeakGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "linux-musl-x64", "conformance/c/host-leak-package"]); const hostLeakGraphBody = JSON.parse(hostLeakGraph.stdout); assert.equal(hostLeakGraphBody.cLibraries[0].targetValidation.hostHeaderLeakage, true); assert.equal(hostLeakGraphBody.cLibraries[0].targetValidation.implicitHostDiscovery, true); assert.equal(hostLeakGraphBody.cLibraries[0].targetValidation.status, "blocked"); const hostLeakReadiness = await execFileAsync(zero, ["check", "--json", "--target", "linux-musl-x64", "conformance/c/host-leak-package"]); const hostLeakReadinessBody = JSON.parse(hostLeakReadiness.stdout); assert.equal(hostLeakReadinessBody.ok, true); assert.equal(hostLeakReadinessBody.diagnostics.length, 0); assert.equal(hostLeakReadinessBody.targetReadiness.ok, false); assert.equal(hostLeakReadinessBody.targetReadiness.buildable, false); assert.equal(hostLeakReadinessBody.targetReadiness.diagnostics[0].code, "CIMP003"); assert.match(hostLeakReadinessBody.targetReadiness.diagnostics[0].help, /target sysroot|vendored/); const hostLeakBuild = await execFileAsync(zero, ["build", "--json", "--target", "linux-musl-x64", "conformance/c/host-leak-package", "--out", ".zero/out/host-leak-package"], { encoding: "utf8" }).catch((error) => error); assert.notEqual(hostLeakBuild.code, 0); const hostLeakBuildBody = JSON.parse(hostLeakBuild.stdout); assert.equal(hostLeakBuildBody.diagnostics[0].code, "CIMP003"); assert.match(hostLeakBuildBody.diagnostics[0].help, /target sysroot|vendored/); const depGraph = await execFileAsync(zero, ["inspect", "--json", "--target", "linux-musl-x64", "conformance/packages/dep-app"]); const depGraphBody = JSON.parse(depGraph.stdout); assert.equal(depGraphBody.package.name, "dep-app"); assert.equal(depGraphBody.package.version, "0.1.0"); assert.equal(depGraphBody.package.resolver.deterministic, true); assert.match(depGraphBody.package.lockfile.path, /\.zero\/package-locks\/[0-9a-f]+\.lock\.json/); assert(depGraphBody.package.dependencies.some((item) => item.name === "dep-lib" && item.status === "path-resolved" && item.targetCompatible === true)); assert(depGraphBody.package.dependencies.some((item) => item.name === "remote-tools" && item.status === "registry-reference" && item.version === "1.2.3")); assert.equal(depGraphBody.packageCache.cacheKeyInputs.compilerVersion, "0.3.4"); assert.equal(depGraphBody.packageCache.cacheKeyInputs.packageVersion, "0.1.0"); assert.match(depGraphBody.packageCache.cacheKeyInputs.dependencyGraphHash, /^[0-9a-f]{16}$/); const depDoc = await execFileAsync(zero, ["doc", "--json", "conformance/packages/dep-app"]); const depDocBody = JSON.parse(depDoc.stdout); assert.equal(depDocBody.package.name, "dep-app"); assert.equal(depDocBody.publicationGate.requiresExamplesForPublicApi, true); assert.equal(depDocBody.packageCache.cacheKeyInputs.packageVersion, "0.1.0"); const depBuild = await execFileAsync(zero, ["build", "--json", "--target", "linux-musl-x64", "conformance/packages/dep-app", "--out", ".zero/out/dep-app"]); const depBuildBody = JSON.parse(depBuild.stdout); assert.equal(depBuildBody.package.dependencies.length, 2); assert.equal(depBuildBody.packageCache.invalidationReasons.includes("dependency graph changed"), true); assert.match(depBuildBody.compilerCaches[0].dependencyGraphHash, /^[0-9a-f]{16}$/); const malformedTomlArrayRoot = `${outDir}/malformed-toml-array`; await rm(malformedTomlArrayRoot, { recursive: true, force: true }); await mkdir(malformedTomlArrayRoot, { recursive: true }); await writeFile(`${malformedTomlArrayRoot}/zero.toml`, `[package] name = "malformed-toml-array" version = "0.1.0" [targets.cli] kind = "exe" main = "src/main.0" [c.libs.demo] headers = ["unterminated] `); const malformedTomlArrayStatus = await execFileAsync(zero, ["status", "--json", malformedTomlArrayRoot]); const malformedTomlArrayBody = JSON.parse(malformedTomlArrayStatus.stdout); assert.equal(malformedTomlArrayBody.ok, true); assert.equal(malformedTomlArrayBody.repositoryGraph.storePresent, false); assert.deepEqual(malformedTomlArrayBody.diagnostics, []); const zeroTestRun = await execFileAsync(zero, ["test", "conformance/native/pass/test-blocks.0"]); assert.equal(zeroTestRun.stdout, "1 test(s) ok\n"); const zeroTestingHelpersRun = await execFileAsync(zero, ["test", "conformance/native/pass/std-testing-helpers-test.0"]); assert.equal(zeroTestingHelpersRun.stdout, "1 test(s) ok\n"); const zeroTestJsonRun = await execFileAsync(zero, ["test", "--json", "--filter", "addition", "conformance/native/pass/test-blocks.0"]); const zeroTestJsonBody = JSON.parse(zeroTestJsonRun.stdout); assert.equal(zeroTestJsonBody.ok, true); assert.equal(zeroTestJsonBody.discoveredTests, 1); assert.equal(zeroTestJsonBody.selectedTests, 1); assert.equal(zeroTestJsonBody.passedTests, 1); assert.equal(zeroTestJsonBody.graph.artifact, "conformance/native/pass/test-blocks.graph"); assert.equal(zeroTestJsonBody.graph.canonicalSource, false); assert.equal(zeroTestJsonBody.graph.moduleIdentity, "module:test-blocks"); assert.equal(zeroTestJsonBody.graph.lowering, "direct-program-graph"); assert.equal(zeroTestJsonBody.testDiscovery.mode, "program-graph"); assert.equal(zeroTestJsonBody.testDiscovery.filter, "addition"); assert.equal(zeroTestJsonBody.fixtures.snapshotKey, "zero-test-graph-native-v1"); assert.equal(zeroTestJsonBody.results[0].status, "passed"); const zeroPtyTargetCapTest = await execFileAsync(zero, ["test", "--json", "--filter", "pty target", "--target", "linux-arm64", "conformance/check/pass/test-target-proc-caps.graph"]).catch((error) => error); assert.notEqual(zeroPtyTargetCapTest.code, 0); const zeroPtyTargetCapBody = JSON.parse(zeroPtyTargetCapTest.stdout); assert.equal(zeroPtyTargetCapBody.ok, false); assert.equal(zeroPtyTargetCapBody.diagnostics[0].code, "PAR100"); assert.match(zeroPtyTargetCapBody.diagnostics[0].actual, /lacks proc/); const zeroTermTargetCapTest = await execFileAsync(zero, ["test", "--json", "--filter", "term target", "--target", "linux-arm64", "conformance/check/pass/test-target-proc-caps.graph"]).catch((error) => error); assert.notEqual(zeroTermTargetCapTest.code, 0); const zeroTermTargetCapBody = JSON.parse(zeroTermTargetCapTest.stdout); assert.equal(zeroTermTargetCapBody.ok, false); assert.equal(zeroTermTargetCapBody.diagnostics[0].code, "PAR100"); assert.match(zeroTermTargetCapBody.diagnostics[0].actual, /lacks proc/); const zeroPackageTestJsonRun = await execFileAsync(zero, ["test", "--json", "conformance/packages/test-app"]); const zeroPackageTestBody = JSON.parse(zeroPackageTestJsonRun.stdout); assert.equal(zeroPackageTestBody.ok, true); assert.equal(zeroPackageTestBody.graph.artifact, "conformance/packages/test-app/zero.graph"); assert.equal(zeroPackageTestBody.graph.canonicalSource, false); assert.equal(zeroPackageTestBody.graph.moduleIdentity, "package:test-app@0.1.0"); assert.equal(zeroPackageTestBody.graph.lowering, "direct-program-graph"); assert.equal(zeroPackageTestBody.testDiscovery.mode, "package-graph"); assert.equal(zeroPackageTestBody.discoveredTests, 3); assert.equal(zeroPackageTestBody.selectedTests, 3); assert.equal(zeroPackageTestBody.expectedFailures, 1); assert(zeroPackageTestBody.fixtures.sourceFiles.some((path) => path.endsWith("helper.0"))); const zeroExpectedFailJsonRun = await execFileAsync(zero, ["test", "--json", "conformance/native/pass/test-expected-fail.0"]); const zeroExpectedFailBody = JSON.parse(zeroExpectedFailJsonRun.stdout); assert.equal(zeroExpectedFailBody.ok, true); assert.equal(zeroExpectedFailBody.expectedFailures, 1); assert.equal(zeroExpectedFailBody.failedTests, 0); assert.equal(zeroExpectedFailBody.results[0].status, "expected-fail"); const fmtRun = await execFileAsync(zero, ["fmt", "conformance/native/pass/test-blocks.0"]); assert.equal(fmtRun.stdout, await readFile("conformance/native/pass/test-blocks.0", "utf8")); const fmtFallibilityRun = await execFileAsync(zero, ["fmt", "conformance/native/pass/fallibility-check-value.0"]); assert.equal(fmtFallibilityRun.stdout, await readFile("conformance/native/pass/fallibility-check-value.0", "utf8")); const fmtImportsRun = await execFileAsync(zero, ["fmt", "conformance/check/pass/imports/src/main.0"]); assert.match(fmtImportsRun.stdout, /use math/); assert.match(fmtImportsRun.stdout, /use types/); const fmtCoreRun = await execFileAsync(zero, ["fmt", "conformance/check/pass/fmt-core-usability.0"]); assert.equal(fmtCoreRun.stdout, await readFile("conformance/check/pass/fmt-core-usability.0", "utf8")); const fmtMessyRun = await execFileAsync(zero, ["fmt", "conformance/format/messy.0"]); assert.equal(fmtMessyRun.stdout, await readFile("conformance/format/messy.0", "utf8")); const fmtIdempotentPath = `${outDir}/fmt-idempotent.0`; await writeFile(fmtIdempotentPath, fmtMessyRun.stdout); const fmtIdempotentRun = await execFileAsync(zero, ["fmt", fmtIdempotentPath]); assert.equal(fmtIdempotentRun.stdout, fmtMessyRun.stdout); const fmtFunctionsBlocksRun = await execFileAsync(zero, ["fmt", "conformance/format/functions-blocks.0"]); assert.equal(fmtFunctionsBlocksRun.stdout, await readFile("conformance/format/functions-blocks.0", "utf8")); const fmtGenericsStaticRun = await execFileAsync(zero, ["fmt", "conformance/format/generics-static.0"]); assert.equal(fmtGenericsStaticRun.stdout, await readFile("conformance/format/generics-static.0", "utf8")); const fmtMatchRun = await execFileAsync(zero, ["fmt", "conformance/format/match-expressions.0"]); assert.equal(fmtMatchRun.stdout, await readFile("conformance/format/match-expressions.0", "utf8")); const helloRunArgs = runnableExeArgs("conformance/run/pass/hello.0", `${outDir}/hello`); if (helloRunArgs) { await rm(`${outDir}/hello`, { force: true }); await execFileAsync(zero, helloRunArgs); const run = await execFileAsync(`${outDir}/hello`, []); assert.match(run.stdout, /hello conformance/); } const packageGraphJson = await execFileAsync(zero, ["inspect", "--json", "conformance/check/pass/package"]); const packageGraph = JSON.parse(packageGraphJson.stdout); assert.deepEqual(packageGraph.sourceFiles.sort(), [ "src/main.0", "src/types.0", "std/codec.0", ]); assert(packageGraph.requiresCapabilities.includes("codec")); assert(packageGraph.requiresCapabilities.includes("parse")); assert(packageGraph.requiresCapabilities.includes("time")); assert.equal(packageGraph.selfHostRouting.cBridge.policy, "removed"); for (const runtimeFixture of [ ["conformance/native/pass/break-continue.0", "break-continue", { stdout: "loop tick\nloop tick\n" }], ["conformance/native/pass/nested-break-continue.0", "nested-break-continue", { stdout: "inner tick\ninner tick\nouter tick\ninner tick\ninner tick\nnested break continue ok\n" }], ["conformance/native/pass/mutref-shape-param.0", "mutref-shape-param", { stdout: "mutref x ok\nmutref y ok\nref sum ok\n" }], ["conformance/native/pass/mutref-shape-param-nested.0", "mutref-shape-param-nested", { stdout: "nested count ok\nnested total ok\nnested flag ok\nnested copy ok\nnested bytes ok\ngeneric mutref ok\n" }], ["conformance/native/pass/untyped-literal-adoption.0", "untyped-literal-adoption", { stdout: "usize literal adoption ok\nflipped literal adoption ok\nliteral arithmetic adoption ok\nu8 literal adoption ok\n" }], ["conformance/native/pass/for-range.0", "for-range", { stdout: "range tick\nrange tick\nrange tick\n" }], ["conformance/native/pass/match-payload-binding.0", "match-payload-binding", { stdout: /payload binding ok/ }], ["conformance/native/pass/match-fallback.0", "match-fallback", { stdout: "match fallback ok\n" }], ["conformance/native/pass/match-choice-fallback.0", "match-choice-fallback", { stdout: "choice fallback ok\n" }], ["conformance/native/pass/null-maybe.0", "null-maybe", { stdout: /null maybe ok/ }], ["conformance/native/pass/maybe-local-null-init-return.0", "maybe-local-null-init-return", { stdout: "maybe local found 42\nmaybe local none\nmaybe local sum 5\n" }], ["conformance/native/pass/top-level-const.0", "top-level-const", { stdout: "const ok\n" }], ["conformance/native/pass/const-arithmetic.0", "const-arithmetic", { stdout: "const arithmetic ok\n" }], ["conformance/native/pass/std-args.0", "std-args", { stdout: "alpha\n", args: ["alpha", "beta"] }], ["conformance/native/pass/std-env.0", "std-env", { stdout: "env ok\n", env: { ZERO_CONFORMANCE_ENV: "agent-env", ZERO_CONFORMANCE_ENV_DELTA: "-3", ZERO_CONFORMANCE_ENV_WORKERS: "5" } }], ["conformance/native/pass/std-hosted-cli.0", "std-hosted-cli", { stdout: "std hosted cli ok\n", args: ["run", "7", "--json", "--name", "agent", "--count", "3", "--enabled", "false", "--delta", "-5", "--size", "9"], env: { ZERO_CONFORMANCE_MODE: "test", ZERO_CONFORMANCE_VERBOSE: "true", ZERO_CONFORMANCE_LIMIT: "9" } }], ["conformance/native/pass/std-proc-helpers.0", "std-proc-helpers", { stdout: "std proc helpers ok\n" }], ["conformance/native/pass/std-proc-capture.0", "std-proc-capture", { stdout: "std proc capture ok\n" }], ["conformance/native/pass/std-proc-capture-files.0", "std-proc-capture-files", { stdout: "std proc capture files ok\n" }], ["conformance/native/pass/std-proc-child.0", "std-proc-child", { stdout: "std proc child ok\n" }], ["conformance/native/pass/std-pty-child.0", "std-pty-child", { stdout: "std pty child ok\n" }], ["conformance/native/pass/std-proc-child-cwd.0", "std-proc-child-cwd", { stdout: "std proc child cwd ok\n" }], ["conformance/native/pass/std-proc-spawn-inherit.0", "std-proc-spawn-inherit", { stdout: "inherit-out status-ok\n" }], ["conformance/native/pass/std-fs.0", "std-fs", { stdout: "fs ok\n", file: { name: "std-fs-write.txt", text: "zero write\n" } }], ["conformance/native/pass/std-fs-bytes.0", "std-fs-bytes", { stdout: "fs bytes ok\n", stderr: "fs bytes err ok\n" }], ["conformance/native/pass/std-fs-write-file-bool.0", "std-fs-write-file-bool", { stdout: "fs write file bool ok\n" }], ["conformance/native/pass/std-fs-append-bytes.0", "std-fs-append-bytes", { stdout: "fs append ok\n" }], ["conformance/native/pass/std-fs-direct-return.0", "std-fs-direct-return", { stdout: "fs direct return ok\n" }], ["conformance/native/pass/std-fs-read-chunks.0", "std-fs-read-chunks", { stdout: "fs read chunks ok\n" }], ["conformance/native/pass/frame-large-locals.0", "frame-large-locals", { stdout: "frame large locals ok alpha\n", args: ["alpha"] }], ["conformance/native/pass/frame-limit-boundary.0", "frame-limit-boundary", { stdout: "frame limit boundary ok\n" }], ["conformance/native/pass/frame-split-helpers.0", "frame-split-helpers", { stdout: "frame split helpers ok\n" }], ["conformance/native/pass/fixed-buf-alloc-local.0", "fixed-buf-alloc-local", { stdout: "fixed buf alloc local ok\n" }], ["conformance/native/pass/std-fs-resource.0", "std-fs-resource", { stdout: "fs resource ok\n", file: { name: "std-fs-resource.txt", text: "zero file\n" } }], ["conformance/native/pass/std-fs-file-helpers.0", "std-fs-file-helpers", { stdout: "std fs file helpers ok\n" }], ["conformance/native/pass/std-io-lines.0", "std-io-lines", { stdout: "std io lines ok\n" }], ["conformance/native/pass/integer-widths.0", "integer-widths", { stdout: "integer widths ok\n" }], ["conformance/native/pass/std-codec-widths.0", "std-codec-widths", { stdout: "codec widths ok\n" }], ["conformance/native/pass/std-csv.0", "std-csv", { stdout: "std csv ok\n" }], ["conformance/native/pass/std-diag.0", "std-diag", { stdout: "std diag ok\n" }], ["conformance/native/pass/std-codec-json-url.0", "std-codec-json-url", { stdout: "std codec json url ok\n" }], ["conformance/native/pass/std-json-cursors.0", "std-json-cursors", { stdout: "std json cursors ok\n" }], ["conformance/native/pass/std-crypto-hmac32.0", "std-crypto-hmac32", { stdout: "crypto hmac32 ok\n" }], ["conformance/native/pass/std-crypto-sha256.0", "std-crypto-sha256", { stdout: "crypto sha256 ok\n" }], ["conformance/native/pass/parse-integers.0", "parse-integers", { stdout: "parse integers ok\n" }], ["conformance/native/pass/std-parse-text.0", "std-parse-text", { stdout: "std parse text ok\n" }], ["conformance/native/pass/explicit-casts.0", "explicit-casts", { stdout: "explicit casts ok\n" }], ["conformance/native/pass/float-char-casts.0", "float-char-casts", { stdout: "float char casts ok\n" }], ["conformance/native/pass/radix-suffix-literals.0", "radix-suffix-literals", { stdout: "radix suffix literals ok\n" }], ["conformance/native/pass/char-literals.0", "char-literals", { stdout: "char literals ok\n" }], ["conformance/native/pass/float-primitives.0", "float-primitives", { stdout: "float primitives ok\n" }], ["conformance/native/pass/recursive-fibonacci.0", "recursive-fibonacci", { stdout: "recursive fibonacci ok\n" }], ["conformance/native/pass/mutual-recursion.0", "mutual-recursion", { stdout: "mutual recursion ok\n" }], ["conformance/native/pass/scratch-nested-index.0", "scratch-nested-index", { stdout: "scratch nested index ok\n" }], ["conformance/native/pass/checked-bounds-get.0", "checked-bounds-get", { stdout: "checked bounds get ok\n" }], ["conformance/native/pass/check-maybe-fallibility.0", "check-maybe-fallibility", { stdout: "check maybe fallibility ok\n" }], ["conformance/native/pass/fallibility-error-sets.0", "fallibility-error-sets", { stdout: "fallibility error sets ok\n" }], ["conformance/native/pass/rescue-check.0", "rescue-check", { stdout: "rescue ok\n" }], ["conformance/native/pass/std-fs-fallible.0", "std-fs-fallible", { stdout: "fs named errors ok\n" }], ["conformance/native/pass/std-fs-fallible-resources.0", "std-fs-fallible-resources", { stdout: "fs fallible resources ok\n" }], ["conformance/native/pass/std-cli-helpers.0", "std-cli-helpers", { stdout: "cli helpers ok\n" }], ["conformance/native/pass/std-mem-copy-fill.0", "std-mem-copy-fill", { stdout: "mem copy fill ok\n" }], ["conformance/native/pass/const-layout.0", "const-layout", { stdout: "const layout ok\n" }], ["conformance/native/pass/c-abi-export.0", "c-abi-export", { stdout: "c abi export ok\n" }], ]) { await assertDirectRuntimeOrUnsupported(...runtimeFixture); } await assertDirectRuntimeRequired("conformance/native/pass/untyped-literal-adoption.0", "untyped-literal-adoption-required", { stdout: "usize literal adoption ok\nflipped literal adoption ok\nliteral arithmetic adoption ok\nu8 literal adoption ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/recursive-multi-call-let.0", "recursive-multi-call-let-required", { stdout: "recursive multi call ok\n" }); const literalAdoptionInitOverflowFixture = `${outDir}/untyped-literal-adoption-init-overflow.0`; const literalAdoptionInitOverflowBody = await writeImportFailureFixture(literalAdoptionInitOverflowFixture, `pub fn main(world: World) -> Void raises { var small: u8 = 300 check world.out.write("unreachable\\n") } `); assert.equal(literalAdoptionInitOverflowBody.diagnostics[0].code, "TYP016"); assert.equal(literalAdoptionInitOverflowBody.diagnostics[0].expected, "u8"); assert.equal(literalAdoptionInitOverflowBody.diagnostics[0].actual, "300 overflows u8"); const literalAdoptionCompareOverflowFixture = `${outDir}/untyped-literal-adoption-compare-overflow.0`; const literalAdoptionCompareOverflowBody = await writeImportFailureFixture(literalAdoptionCompareOverflowFixture, `pub fn main(world: World) -> Void raises { var small: u8 = 7 if 300 > small { check world.out.write("unreachable\\n") } } `); assert.equal(literalAdoptionCompareOverflowBody.diagnostics[0].code, "TYP016"); assert.equal(literalAdoptionCompareOverflowBody.diagnostics[0].expected, "u8"); assert.equal(literalAdoptionCompareOverflowBody.diagnostics[0].actual, "300 overflows u8"); assert.match(literalAdoptionCompareOverflowBody.diagnostics[0].help, /smaller literal or a wider integer type/); const fixedArrayRepeatLengthFixture = `${outDir}/fixed-array-repeat-length-mismatch.0`; const fixedArrayRepeatLengthBody = await writeImportFailureFixture(fixedArrayRepeatLengthFixture, `pub fn main(world: World) -> Void raises { var b: [64]u8 = [0_u8; 32] b[0] = 1 check world.out.write("unreachable\\n") } `); assert.equal(fixedArrayRepeatLengthBody.diagnostics[0].code, "TYP002"); assert.equal(fixedArrayRepeatLengthBody.diagnostics[0].expected, "[64]u8"); assert.equal(fixedArrayRepeatLengthBody.diagnostics[0].actual, "repeat count 32"); assert.match(fixedArrayRepeatLengthBody.diagnostics[0].help, /make the lengths agree/); const fixedArrayListLengthFixture = `${outDir}/fixed-array-list-length-mismatch.0`; const fixedArrayListLengthBody = await writeImportFailureFixture(fixedArrayListLengthFixture, `pub fn main(world: World) -> Void raises { var b: [4]u8 = [1, 2] b[0] = 1 check world.out.write("unreachable\\n") } `); assert.equal(fixedArrayListLengthBody.diagnostics[0].code, "TYP002"); assert.equal(fixedArrayListLengthBody.diagnostics[0].expected, "[4]u8"); assert.equal(fixedArrayListLengthBody.diagnostics[0].actual, "2 element(s)"); assert.match(fixedArrayListLengthBody.diagnostics[0].help, /annotate the intended array length/); await assertDirectRuntimeRequired("conformance/native/pass/break-continue.0", "break-continue-required", { stdout: "loop tick\nloop tick\n" }); await assertDirectRuntimeRequired("conformance/native/pass/maybe-local-null-init-return.0", "maybe-local-null-init-return-required", { stdout: "maybe local found 42\nmaybe local none\nmaybe local sum 5\n" }); await assertDirectRuntimeRequired("conformance/native/pass/top-level-const.0", "top-level-const-required", { stdout: "const ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/const-arithmetic.0", "const-arithmetic-required", { stdout: "const arithmetic ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/nested-break-continue.0", "nested-break-continue-required", { stdout: "inner tick\ninner tick\nouter tick\ninner tick\ninner tick\nnested break continue ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/mutref-shape-param.0", "mutref-shape-param-required", { stdout: "mutref x ok\nmutref y ok\nref sum ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/mutref-shape-param-nested.0", "mutref-shape-param-nested-required", { stdout: "nested count ok\nnested total ok\nnested flag ok\nnested copy ok\nnested bytes ok\ngeneric mutref ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-function-basic.0", "generic-function-basic-required", { stdout: "generic function ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-nested-calls.0", "generic-nested-calls-required", { stdout: "generic nested calls ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-inferred-specialized-call.0", "generic-inferred-specialized-call-required", { stdout: "generic inferred specialized call ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-nested-local-specialization.0", "generic-nested-local-specialization-required", { stdout: "generic nested local specialization ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-static-array-specialization.0", "generic-static-array-specialization-required", { stdout: "generic static array specialization ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/generic-static-forwarded-array-specialization.0", "generic-static-forwarded-array-specialization-required", { stdout: "generic static forwarded array specialization ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/explicit-cast-narrow-direct.0", "explicit-cast-narrow-direct-required", { stdout: "explicit cast narrow direct ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/frame-large-locals.0", "frame-large-locals-required", { stdout: "frame large locals ok alpha\n", args: ["alpha"] }); await assertDirectRuntimeRequired("conformance/native/pass/frame-limit-boundary.0", "frame-limit-boundary-required", { stdout: "frame limit boundary ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/frame-split-helpers.0", "frame-split-helpers-required", { stdout: "frame split helpers ok\n" }); await assertDirectRuntimeRequired("conformance/native/pass/fixed-buf-alloc-local.0", "fixed-buf-alloc-local-required", { stdout: "fixed buf alloc local ok\n" }); const frameLimitOverFixture = `${outDir}/frame-limit-over.0`; const frameLimitOverBody = await writeImportFailureFixture(frameLimitOverFixture, `pub fn main(world: World) -> Void raises { var buffer: [262144]u8 = [0; 262144] buffer[0] = 1 check world.out.write("unreachable\\n") } `); assert.equal(frameLimitOverBody.diagnostics[0].code, "MEM003"); assert.match(frameLimitOverBody.diagnostics[0].expected, /131072 bytes of locals/); assert.match(frameLimitOverBody.diagnostics[0].actual, /262144 bytes of locals/); assert.match(frameLimitOverBody.diagnostics[0].help, /smaller buffers in helper functions/); // Typed graph MIR constructs outside the buildable subset fail at import // time with the same BLD004 diagnostics zero build would report later. const pageAllocLocalBody = await writeImportFailureFixture(`${outDir}/page-alloc-local.0`, `pub fn main(world: World) -> Void raises { let page: PageAlloc = std.mem.pageAlloc() let bytes: Maybe> = std.mem.allocBytes(page, 4096) if bytes.has { check world.out.write("unreachable\\n") } } `); assert.equal(pageAllocLocalBody.diagnostics[0].code, "BLD004"); assert.match(pageAllocLocalBody.diagnostics[0].message, /allocator local requires FixedBufAlloc/); assert.equal(pageAllocLocalBody.diagnostics[0].actual, "PageAlloc"); assert.equal(pageAllocLocalBody.diagnostics[0].line, 2); assert.match(pageAllocLocalBody.diagnostics[0].help, /std\.mem\.fixedBufAlloc/); assert.match(pageAllocLocalBody.diagnostics[0].help, /do not lower to direct backends yet/); const generalAllocLocalBody = await writeImportFailureFixture(`${outDir}/general-alloc-local.0`, `pub fn main(world: World) -> Void raises { let general: GeneralAlloc = std.mem.generalAlloc() let bytes: Maybe> = std.mem.allocBytes(general, 64) if bytes.has { check world.out.write("unreachable\\n") } } `); assert.equal(generalAllocLocalBody.diagnostics[0].code, "BLD004"); assert.equal(generalAllocLocalBody.diagnostics[0].actual, "GeneralAlloc"); assert.equal(generalAllocLocalBody.diagnostics[0].line, 2); const deferStatementBody = await writeImportFailureFixture(`${outDir}/defer-statement-gate.0`, `pub fn main(world: World) -> Void raises { defer check world.out.write("bye\\n") check world.out.write("hi\\n") } `); assert.equal(deferStatementBody.diagnostics[0].code, "BLD004"); assert.match(deferStatementBody.diagnostics[0].message, /statement kind is unsupported/); assert.equal(deferStatementBody.diagnostics[0].actual, "Defer"); assert.equal(deferStatementBody.diagnostics[0].line, 2); assert.equal(deferStatementBody.diagnostics[0].column, 5); const rescueNonPrimitiveBody = await writeImportFailureFixture(`${outDir}/rescue-non-primitive-gate.0`, `fn label(ok: Bool) -> String raises [Invalid] { if ok { return "primary" } raise Invalid } pub fn main(world: World) -> Void raises { let value: String = rescue label(false) err "fallback" check world.out.write(value) } `); assert.equal(rescueNonPrimitiveBody.diagnostics[0].code, "BLD004"); assert.equal(rescueNonPrimitiveBody.diagnostics[0].actual, "String"); assert.equal(rescueNonPrimitiveBody.diagnostics[0].line, 1); const refByteBufParamBody = await writeImportFailureFixture(`${outDir}/ref-bytebuf-param-gate.0`, `fn buffered(buf: ref) -> usize { return std.mem.bufLen(buf) } pub fn main(world: World) -> Void raises { var storage: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0] var alloc: FixedBufAlloc = std.mem.fixedBufAlloc(storage) let maybe: Maybe> = std.mem.byteBuf(alloc, 4) if !maybe.has { return } let buf: owned = maybe.value if buffered(&buf) == 4 { check world.out.write("buffered\\n") } } `); assert.equal(refByteBufParamBody.diagnostics[0].code, "BLD004"); assert.equal(refByteBufParamBody.diagnostics[0].actual, "ref"); assert.equal(refByteBufParamBody.diagnostics[0].line, 1); await assertDirectRuntimeRequired("conformance/run/pass/world-output-helper.0", "world-output-helper-required", { stdout: "world helper ok\n" }); const codecReadU32Body = await writeImportFailureFixture(`${outDir}/codec-readu32-gate.0`, `use std.codec pub fn main(world: World) -> Void raises { let value: u32 = std.codec.readU32("abcd") if value > 0 { check world.out.write("read\\n") } } `); assert.equal(codecReadU32Body.diagnostics[0].code, "STD002"); assert.match(codecReadU32Body.diagnostics[0].message, /unknown std helper/); assert.equal(codecReadU32Body.diagnostics[0].actual, "unknown std helper"); assert.equal(codecReadU32Body.diagnostics[0].line, 4); const enumLocalPackage = `${outDir}/enum-local-package`; await mkdir(`${enumLocalPackage}/src`, { recursive: true }); await writeZeroToml(enumLocalPackage, { package: { name: "enum-local-package", version: "0.1.0" }, targets: { cli: { kind: "exe", main: "src/main.0" } }, deps: {}, }); await writeFile(`${enumLocalPackage}/src/main.0`, `enum Status { ready, failed, } choice Outcome { ok, failed: i32, } pub fn main(world: World) -> Void raises { let status: Status = Status.ready let outcome: Outcome = Outcome.ok if status == Status.ready { check world.out.write("ready\\n") } } `); const enumLocalImport = await execFileAsync(zero, ["import", "--json", enumLocalPackage]).catch((error) => error); assert.notEqual(enumLocalImport.code, 0); const enumLocalImportBody = JSON.parse(enumLocalImport.stdout); assert.equal(enumLocalImportBody.diagnostics[0].code, "BLD004"); assert.match(enumLocalImportBody.diagnostics[0].message, /local type is unsupported/); assert.equal(enumLocalImportBody.diagnostics[0].actual, "Status"); assert.match(enumLocalImportBody.diagnostics[0].path, /src\/main\.0$/); assert.equal(enumLocalImportBody.diagnostics[0].line, 12); const abiDump = await execFileAsync(zero, ["abi", "dump", "--json", "conformance/native/pass/const-layout.0"]); const abiDumpBody = JSON.parse(abiDump.stdout); assert.equal(abiDumpBody.schemaVersion, 1); assert.equal(abiDumpBody.pointerSize, 8); assert(abiDumpBody.externShapes.some((item) => item.name === "CPoint" && item.size === 8 && item.fields[1].offset === 4)); assert(abiDumpBody.primitiveLayouts.some((item) => item.name === "usize" && item.size === 8)); const cAbiDump = await execFileAsync(zero, ["abi", "dump", "--json", "conformance/native/pass/c-abi-export.0"]); const cAbiDumpBody = JSON.parse(cAbiDump.stdout); assert(cAbiDumpBody.cExports.some((item) => item.name === "zero_add" && item.cReturnType === "int32_t")); assert.equal(cAbiDumpBody.generatedHeader.available, true); assert.match(cAbiDumpBody.generatedHeader.text, /int32_t zero_add\(int32_t a, int32_t b\);/); const abiCheck = await execFileAsync(zero, ["abi", "check", "--json", "conformance/native/pass/const-layout.0"]); assert.equal(JSON.parse(abiCheck.stdout).ok, true); for (const runtimeFixture of [ ["conformance/native/pass/indexing-primitives.0", "indexing-primitives", { stdout: "indexing primitives ok\n" }], ["conformance/native/pass/range-slices.0", "range-slices", { stdout: "range slices ok\n" }], ["conformance/native/pass/byte-view-call-single-eval.0", "byte-view-call-single-eval", { stdout: "byte view call single eval ok\n" }], ["conformance/native/pass/std-math-breadth.0", "std-math-breadth", { stdout: "std math breadth ok\n" }], ["conformance/native/pass/std-numeric-random-time.0", "std-numeric-random-time", { stdout: "std numeric random time ok\n" }], ["conformance/native/pass/std-regex.0", "std-regex", { stdout: "std regex ok\n" }], ["conformance/native/pass/std-unicode.0", "std-unicode", { stdout: "std unicode ok\n" }], ["conformance/native/pass/std-inet.0", "std-inet", { stdout: "std inet ok\n" }], ["conformance/native/pass/std-time-rfc3339.0", "std-time-rfc3339", { stdout: "std time rfc3339 ok\n" }], ["conformance/native/pass/std-str-breadth.0", "std-str-breadth", { stdout: "std str breadth ok\n" }], ["conformance/native/pass/std-mem-generic-items.0", "std-mem-generic-items", { stdout: "std mem generic items ok\n" }], ["conformance/native/pass/std-mem-field-items.0", "std-mem-field-items", { stdout: "std mem field items ok\n" }], ["conformance/native/pass/std-mem-byte-field-copy.0", "std-mem-byte-field-copy", { stdout: "std mem byte field copy ok\n" }], ["conformance/native/pass/std-mem-bool-copy-items.0", "std-mem-bool-copy-items", { stdout: "std mem bool copy items ok\n" }], ["conformance/native/pass/std-mem-u64-contains.0", "std-mem-u64-contains", { stdout: "std mem u64 contains ok\n" }], ["conformance/native/pass/std-mem-u64-copy-items.0", "std-mem-u64-copy-items", { stdout: "std mem u64 copy items ok\n" }], ["conformance/native/pass/std-mem-local-u64-copy-items.0", "std-mem-local-u64-copy-items", { stdout: "std mem local u64 copy items ok\n" }], ["conformance/native/pass/std-path-helper-name-collision.0", "std-path-helper-name-collision", { stdout: "std path helper collision ok\n" }], ["conformance/native/pass/byte-view-params.0", "byte-view-params", { stdout: "byte view params ok\n" }], ["conformance/native/pass/bool-arrays.0", "bool-arrays", { stdout: "bool arrays ok\n" }], ["conformance/native/pass/generic-spans.0", "generic-spans", { stdout: "generic spans ok\n" }], ["conformance/native/pass/open-ended-slices.0", "open-ended-slices", { stdout: "open ended slices ok\n" }], ["conformance/native/pass/string-slices.0", "string-slices", { stdout: "string slices ok\n" }], ["conformance/native/pass/indexed-mutation.0", "indexed-mutation", { stdout: "indexed mutation ok\n" }], ["conformance/native/pass/dynamic-indexed-store-scratch.0", "dynamic-indexed-store-scratch", { stdout: "dynamic indexed store ok\n" }], ["conformance/native/pass/nested-lvalues.0", "nested-lvalues", { stdout: "nested lvalues ok\n" }], ["conformance/native/pass/mutable-spans.0", "mutable-spans", { stdout: "mutable spans ok\n" }], ["conformance/native/pass/mutref-indexed-lvalues.0", "mutref-indexed-lvalues", { stdout: "mutref indexed lvalues ok\n" }], ["conformance/native/pass/generic-mem.0", "generic-mem", { stdout: "generic mem ok\n" }], ["conformance/native/pass/generic-nested-calls.0", "generic-nested-calls", { stdout: "generic nested calls ok\n" }], ["conformance/native/pass/generic-multi-specialization.0", "generic-multi-specialization", { stdout: "generic multi specialization ok\n" }], ["conformance/native/pass/generic-inferred-specialized-call.0", "generic-inferred-specialized-call", { stdout: "generic inferred specialized call ok\n" }], ["conformance/native/pass/generic-nested-local-specialization.0", "generic-nested-local-specialization", { stdout: "generic nested local specialization ok\n" }], ["conformance/native/pass/generic-static-array-specialization.0", "generic-static-array-specialization", { stdout: "generic static array specialization ok\n" }], ["conformance/native/pass/generic-static-forwarded-array-specialization.0", "generic-static-forwarded-array-specialization", { stdout: "generic static forwarded array specialization ok\n" }], ["conformance/native/pass/static-interface-mutref.0", "static-interface-mutref", { stdout: "static interface mutref ok\n" }], ["conformance/native/pass/owned-transfer.0", "owned-transfer", { stdout: "owned transfer ok\n" }], ["conformance/native/pass/owned-drop-cleanup.0", "owned-drop-cleanup", { stdout: "owned drop cleanup ok\n" }], ["conformance/native/pass/owned-drop-move-suppressed.0", "owned-drop-move-suppressed", { stdout: "owned drop move suppressed ok\n" }], ["conformance/native/pass/borrow-primitives.0", "borrow-primitives", { stdout: "borrow primitives ok\n" }], ["conformance/native/pass/allocator-primitives.0", "allocator-primitives", { stdout: "allocator primitives ok\n" }], ["conformance/native/pass/owned-byte-buffer.0", "owned-byte-buffer", { stdout: "owned byte buffer ok\n" }], ]) { await assertDirectRuntimeOrUnsupported(...runtimeFixture); } finishAggregateAssert(assert, { suite: "conformance", reportPath: `${outDir}/failures.json` }); console.log("conformance ok");