P5.7 Step A: VM is the sole comptime evaluator at emit-time + type-fn sites (no fallback)
Remove the comptime_flat/need_vm gate and the vm_result-orelse-legacy fallback from emit_llvm.zig (runComptimeSideEffects + emitGlobals const-init) and comptime.zig (runComptimeTypeFunc). The comptime VM now always runs; a bail is always a build-gating diagnostic, never a fallback. Delete the now-moot entryNeedsVm. runComptimeSideEffects drops the Interpreter entirely (VM writes #run output direct to fd 1); emitGlobals keeps a fresh interp_inst only as the valueToLLVMConst materialization context (the regToValue bridge, removed with interp.zig in a later step). #insert (evalComptimeString) still routes through the legacy interp — deferred until interp.zig deletion. Reconcile 1654: the comptime asm-global #run now reports the VM's clean dlsym bail instead of the legacy CannotEvalComptime wrapper (exit still 1). 501/501 unit + 706/0 corpus.
This commit is contained in:
@@ -506,74 +506,33 @@ pub fn runComptimeTypeFunc(self: *Lowering, func_id: FuncId, span: ast.Span) ?Ty
|
||||
}
|
||||
}
|
||||
|
||||
var interp = interp_mod.Interpreter.init(self.module, self.alloc);
|
||||
defer interp.deinit();
|
||||
if (self.diagnostics) |d| if (d.import_sources) |sm| interp.setSourceMap(sm);
|
||||
interp.setMintTable(&self.module.types);
|
||||
|
||||
// Clear the interp's last-bail channel so a bail HERE is attributable to
|
||||
// THIS construction (not a stale message from an earlier comptime eval).
|
||||
interp_mod.Interpreter.last_bail_detail = null;
|
||||
|
||||
// Flat-memory VM fast path (gated by `-Dcomptime-flat` / `SX_COMPTIME_FLAT`),
|
||||
// the THIRD comptime call site after the two emit-time folds. A type-fn runs
|
||||
// on the VM; `null` (any bail) falls through to the legacy interpreter below,
|
||||
// which mints identically. The VM bails BEFORE any table mutation — its
|
||||
// compiler-WRITE fns (declare_type/register_type/pointer_to) aren't ported to
|
||||
// `callCompilerFn`, and it can't yet model a `Type` result — so a minting
|
||||
// type-fn bails at the first write call (no partial mint → no double-mint).
|
||||
// The VM is hardened against malformed lowering-time IR (it BAILS, never
|
||||
// panics; see `comptime_vm.refTy`/`badRef`). Today this is near-pure fallback;
|
||||
// it lights up as `Type` modeling + the VM-native write side land.
|
||||
// Strict mode implies flat (run the VM, then hard-error instead of falling back).
|
||||
const comptime_flat = build_opts.comptime_flat or std.c.getenv("SX_COMPTIME_FLAT") != null or
|
||||
build_opts.comptime_flat_strict or std.c.getenv("SX_COMPTIME_FLAT_STRICT") != null;
|
||||
const vm_result: ?interp_mod.Value = if (comptime_flat)
|
||||
comptime_vm.tryEval(self.alloc, self.module, func_id, null, null)
|
||||
else
|
||||
null;
|
||||
if (comptime_flat and std.c.getenv("SX_COMPTIME_FLAT_TRACE") != null) {
|
||||
// The comptime VM is the SOLE evaluator (P5.7) — no legacy fallback. A
|
||||
// type-fn runs on the VM; a bail is ALWAYS a build-gating diagnostic, never a
|
||||
// fallback. The VM is hardened against malformed lowering-time IR (it BAILS,
|
||||
// never panics; see `comptime_vm.refTy`/`badRef`), and bails BEFORE any table
|
||||
// mutation, so a failed mint never leaves a partial type.
|
||||
const vm_result = comptime_vm.tryEval(self.alloc, self.module, func_id, null, null);
|
||||
if (std.c.getenv("SX_COMPTIME_FLAT_TRACE") != null) {
|
||||
if (vm_result != null)
|
||||
std.debug.print("[comptime-vm] HANDLED type-fn\n", .{})
|
||||
else
|
||||
std.debug.print("[comptime-vm] fallback type-fn: {s}\n", .{comptime_vm.last_bail_reason orelse "<unknown>"});
|
||||
std.debug.print("[comptime-vm] BAIL type-fn: {s}\n", .{comptime_vm.last_bail_reason orelse "<unknown>"});
|
||||
}
|
||||
if (vm_result) |v| {
|
||||
const tid_vm = v.asTypeId() orelse return null;
|
||||
return checkComptimeTypeResult(self, tid_vm, span);
|
||||
}
|
||||
|
||||
// Strict mode: NO fallback — render the VM's bail reason as the SAME
|
||||
// build-gating diagnostic the non-strict legacy path emits below (the VM and
|
||||
// legacy set identical detail strings, e.g. "comptime define(): duplicate
|
||||
// variant name 'x'"), so a comptime type-construction failure (1179/1180)
|
||||
// produces its proper user diagnostic with no legacy interp in the loop — the
|
||||
// 4B step toward deleting the fallback. (4B / VM-native diagnostics.)
|
||||
if (build_opts.comptime_flat_strict or std.c.getenv("SX_COMPTIME_FLAT_STRICT") != null) {
|
||||
if (self.diagnostics) |d| {
|
||||
d.addFmt(.err, span, "comptime type construction failed: {s}", .{comptime_vm.last_bail_reason orelse "<unknown>"});
|
||||
}
|
||||
return null;
|
||||
// VM bailed: render a build-gating diagnostic naming the reason — NOT poison
|
||||
// to `.unresolved` silently and let that crash at LLVM emission ("unresolved
|
||||
// type reached LLVM emission") or hide behind a downstream cascade (issue
|
||||
// 0140). The VM's bail reason carries the precise cause (e.g. "comptime
|
||||
// define(): duplicate variant name 'x'"), so a comptime type-construction
|
||||
// failure (1179/1180) produces its proper user diagnostic.
|
||||
if (self.diagnostics) |d| {
|
||||
d.addFmt(.err, span, "comptime type construction failed: {s}", .{comptime_vm.last_bail_reason orelse "<unknown>"});
|
||||
}
|
||||
|
||||
const result = interp.call(func_id, &.{}) catch |err| {
|
||||
// A comptime type construction (declare/define, reflection) that bails
|
||||
// must surface a build-gating diagnostic naming the reason — NOT poison
|
||||
// to `.unresolved` silently and let that crash at LLVM emission
|
||||
// ("unresolved type reached LLVM emission") or hide behind a downstream
|
||||
// cascade (issue 0140). The interp's `bailDetail` already set the precise
|
||||
// reason; mirror the `#run` path (emit_llvm.zig) and render it. Returning
|
||||
// null keeps the `.unresolved` poison for the caller, but now the build
|
||||
// is gated by a real message, so no unresolved type reaches emission
|
||||
// unannounced.
|
||||
if (self.diagnostics) |d| {
|
||||
const detail = interp_mod.Interpreter.last_bail_detail orelse @errorName(err);
|
||||
d.addFmt(.err, span, "comptime type construction failed: {s}", .{detail});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const tid = result.asTypeId() orelse return null;
|
||||
return checkComptimeTypeResult(self, tid, span);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Post-check a comptime type-construction result (shared by the VM and legacy
|
||||
|
||||
Reference in New Issue
Block a user