os: graduate tryopen/trywrite/tryread to (T | oserror)

Final piece of the os module graduation: the three try* wrappers
move off the (T | str) placeholder shape. `oserror` becomes a real
Hare-style error type (`!i64` instead of plain `i64`), so it's
picked up by ?-propagation as the error half without callers having
to name it.

tryread:  (i64 | oserror)   was (i64 | str)
trywrite: (i64 | oserror)   was (i64 | str)
tryopen:  (i32 | oserror)   was (i32 | str)

Callsites updated: wwdump uses tryopen; the e2e trywrite probe
matches on os.oserror and validates -EBADF for a bad fd (-9 instead
of the old "write failed" string length).

selfhost/test/smoke.ww switched to raw os.open(2) instead of
os.tryopen for probe 7 — same reason as the os.readall switch in
the prior commit: probe 6 in 990_selfhost compiles smoke.ww
standalone, and cross-module type refs like `os.oserror` don't
resolve in that mode.
This commit is contained in:
2026-05-12 02:42:49 +09:00
parent 594a2bad62
commit d9041ab45e
7 changed files with 76 additions and 72 deletions

View File

@@ -152,12 +152,12 @@ export fn main() i32 = {
// Probe 7 — file open/read via the new os APIs. /proc/self/cmdline
// always exists on Linux, no write side, and is non-empty.
let path: str = "/proc/self/cmdline";
let fd_or_err: (i32 | str) = os.tryopen(path.ptr, os.O_RDONLY, 0i32);
let fd: i32 = 0;
match (fd_or_err) {
case let v: i32 => fd = v;
case let e: str => return 21;
};
// Use raw os.open here (returns i32 with -errno) for the same
// reason as os.read below: probe 6 in 990_selfhost compiles
// smoke.ww standalone (no `use` expansion), so cross-module type
// references like `os.oserror` don't resolve at that step.
let fd: i32 = os.open(path.ptr, os.O_RDONLY, 0i32);
if (fd < 0) { return 21; };
let rbuf: [128]u8;
// Use raw os.read here (single syscall, plain i64) instead of
// os.readall: the 990 cgen-match probe compiles smoke.ww