ERR/E4.2: value-carrying -> (int, !) main wrapper
Extends the failable-main entry-point wrapper to a value-carrying main.
`main :: () -> (int, !)` now exits the integer value on success (truncated
to u8, like a plain integer main) and reports the header + trace to stderr
+ exits 1 on an escaping error (same reporter as the pure `-> !` form).
- lower.zig validateMainSignature: accept a 2-field `{int, error_set}`
tuple return (set needs_trace_runtime) instead of rejecting it. Multi-
value `-> (T1, T2, !)` and non-integer value slots still reject — there's
no single integer exit code to map them to (sharpened diagnostic).
- emit_llvm.zig: the `.ret` arm detects a value-carrying main (tuple ending
in `.error_set`) and extracts `{value, tag}` (extractvalue 0/1) before
calling emitFailableMainRet, now generalized to take an optional `value`
(null → pure `-> !`, success exits 0; present → success exits the value).
C reporter unchanged.
All E4.2 entry-point shapes (void / int / `-> !` / `-> (int, !)`) now done.
examples/245-failable-main-value.sx (exit 64); 239 comment refreshed.
This commit is contained in:
@@ -397,9 +397,19 @@ pub const Lowering = struct {
|
||||
self.needs_trace_runtime = true;
|
||||
return;
|
||||
}
|
||||
// `-> (T..., !)` — a multi-slot tuple return; not yet wired.
|
||||
// `-> (T, !)` — value-carrying failable. Accepted only for a single
|
||||
// **integer** value slot (`{int, error_set}`): the wrapper extracts
|
||||
// the value + tag from the returned tuple, exits `value as u8` on
|
||||
// success / reports + exits 1 on error. Multi-value `-> (T1, T2, !)`
|
||||
// or a non-integer value slot stays rejected — there's no single
|
||||
// integer exit code to map it to.
|
||||
const ti = self.module.types.get(rt);
|
||||
if (ti == .tuple and ti.tuple.fields.len == 2 and self.isIntEx(ti.tuple.fields[0])) {
|
||||
self.needs_trace_runtime = true;
|
||||
return;
|
||||
}
|
||||
if (self.diagnostics) |diags| {
|
||||
diags.addFmt(.err, if (fd.return_type) |rtn| rtn.span else null, "a value-carrying failable `main` (`-> (T, !)`) is not yet supported — its multi-slot return ABI-mismatches the entry-point call; use `-> !` (no value) or a non-failable integer return, or absorb errors with `catch`", .{});
|
||||
diags.addFmt(.err, if (fd.return_type) |rtn| rtn.span else null, "a value-carrying failable `main` must be `-> (int, !)` (one integer value slot); got '{s}'. Use `-> !` (no value), `-> (int, !)`, or a non-failable integer return", .{self.formatTypeName(rt)});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user