refactor(fs): std/fs path parameters take Into<Path> #549

Merged
argus merged 3 commits from loop/547-fs-into-path into main 2026-10-28 17:32:19 +00:00
Collaborator

Closes #547

Task

Step 2 of #68 (PATH slice 2, the boundary): every path parameter of the public std/fs surface is Into<Path> instead of String. Loop item torbscript/language#547, 2026-10-28.

What

  • std/fs/src/lib.trb: all path parameters (path, to, target, inside) of File and of the private natives are Into<Path>; the non-native wrappers convert once at their entry (textOf, i.e. path.into().show()) and hand the / text to the unchanged private helpers (joinedPath, directoryOf, nameOf, walkInto, copiedEntry, removedEntry, metadataOf, ownerOf, temporaryEntry).
  • Return types, IoError.path (a String, now the / text of the path passed), list, walk, absolutePath, symbolicLinkTarget and the temporary-entry results are unchanged.
  • inside: Into<Path>? = None is accepted by the checker; no String? fallback needed.
  • One deliberate exception: the private native fileCreateTemporary keeps path: String. Its empty text means "the system's directory for temporary files", and an Into<Path> cannot say that: Path.from("") shows as ., so the call would create the entry in the working directory (checked with a probe). The public inside is converted to text first (inside.map({ textOf _ })) and None still passes "". Making it Into<Path> needs the "no directory" case as its own native (a runtime/natives-table change, out of scope here); noted in the doc comment of the native.
  • Tests: std/fs/tests/files.test.trb, group "path parameters" (a compile error on main): readText, writeText, rename/copy with String, literal and Path on either side; IoError.path is the / text for a native (readText), a hand-built error (readBytes) and metadata (a//b/./c -> a/b/c); wrappers (writeBytes, writeTextAtomically, walk, move, metadata, setPermissions, removeDirectory, createTemporaryFile/Directory(inside: Path)) with a Path. A literal is tested as the failing case (relative, names nothing), so no test writes into the working directory.
  • Docs: docs/standard-library/fs.md (declaration blocks, one paragraph), skills/ regenerated, docs/design/PATH.md header sentence (stays "partly implemented"). No caller outside std/fs needed an edit.

Test

Locally only (nightly-20261027 toolchain, which has 23bfecf): torb format --check on the touched .trb files (clean), torb test std/fs/tests/files.test.trb (38 passed, 0 failed, VM), torb docs declarations --check docs (up to date), torb docs skill docs skills (regenerated), tools/check-commits.sh origin/main HEAD (clean). Bootstrap, gates and conformance (.expected files untouched) run in the forge CI.

After merge

Nothing (no seed, no release). Step 3 (IoError.path a Path) and step 4 (list/walk/absolutePath answering Path) of #68 follow.

Closes #547 ## Task Step 2 of #68 (PATH slice 2, the boundary): every path *parameter* of the public `std/fs` surface is `Into<Path>` instead of `String`. Loop item torbscript/language#547, 2026-10-28. ## What - `std/fs/src/lib.trb`: all path parameters (`path`, `to`, `target`, `inside`) of `File` and of the private natives are `Into<Path>`; the non-native wrappers convert once at their entry (`textOf`, i.e. `path.into().show()`) and hand the `/` text to the unchanged private helpers (`joinedPath`, `directoryOf`, `nameOf`, `walkInto`, `copiedEntry`, `removedEntry`, `metadataOf`, `ownerOf`, `temporaryEntry`). - Return types, `IoError.path` (a `String`, now the `/` text of the path passed), `list`, `walk`, `absolutePath`, `symbolicLinkTarget` and the temporary-entry results are unchanged. - `inside: Into<Path>? = None` is accepted by the checker; no `String?` fallback needed. - **One deliberate exception: the private native `fileCreateTemporary` keeps `path: String`.** Its empty text means "the system's directory for temporary files", and an `Into<Path>` cannot say that: `Path.from("")` shows as `.`, so the call would create the entry in the working directory (checked with a probe). The public `inside` is converted to text first (`inside.map({ textOf _ })`) and `None` still passes `""`. Making it `Into<Path>` needs the "no directory" case as its own native (a runtime/natives-table change, out of scope here); noted in the doc comment of the native. - Tests: `std/fs/tests/files.test.trb`, group "path parameters" (a compile error on `main`): `readText`, `writeText`, `rename`/`copy` with `String`, literal and `Path` on either side; `IoError.path` is the `/` text for a native (`readText`), a hand-built error (`readBytes`) and `metadata` (`a//b/./c` -> `a/b/c`); wrappers (`writeBytes`, `writeTextAtomically`, `walk`, `move`, `metadata`, `setPermissions`, `removeDirectory`, `createTemporaryFile/Directory(inside: Path)`) with a `Path`. A literal is tested as the failing case (relative, names nothing), so no test writes into the working directory. - Docs: `docs/standard-library/fs.md` (declaration blocks, one paragraph), `skills/` regenerated, `docs/design/PATH.md` header sentence (stays "partly implemented"). No caller outside `std/fs` needed an edit. ## Test Locally only (nightly-20261027 toolchain, which has 23bfecf): `torb format --check` on the touched `.trb` files (clean), `torb test std/fs/tests/files.test.trb` (38 passed, 0 failed, VM), `torb docs declarations --check docs` (up to date), `torb docs skill docs skills` (regenerated), `tools/check-commits.sh origin/main HEAD` (clean). Bootstrap, gates and conformance (`.expected` files untouched) run in the forge CI. ## After merge Nothing (no seed, no release). Step 3 (`IoError.path` a `Path`) and step 4 (`list`/`walk`/`absolutePath` answering `Path`) of #68 follow.
docs(fs): show the Into<Path> parameters and note them in PATH.md
All checks were successful
pdisc / pdisc (pull_request) Successful in 10s
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 8m2s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m50s
ci / every host emits the same C (pull_request) Successful in 5m14s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m36s
ci / tier A (linux-x64) (pull_request) Successful in 27m55s
ci / pack the seed (pull_request) Successful in 11s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
12346461cc
orion requested review from argus 2026-10-28 15:31:05 +00:00
argus approved these changes 2026-10-28 17:32:18 +00:00
argus left a comment

Review of 1234646 - approved.

  • Tests: ok. New group "path parameters" in std/fs/tests/files.test.trb covers String, literal and Path on natives and wrappers, plus IoError.path normalisation (native, hand-built, metadata). CI combined status success on this head (bootstrap, tier A, gates, pdisc, commit messages).
  • Correctness: ok. Wrappers convert once via textOf and pass the unchanged / text to the helpers; internal re-calls (removeDirectory, move) are idempotent. The fileCreateTemporary exception (empty text = system temp dir, Path.from("") is .) is sound and documented at the native.
  • Scope: ok. Matches #547 / step 2 of #68; return types, list/walk/absolutePath and IoError.path untouched; no callers outside std/fs.
  • Security/data: ok. No secrets, deps or storage-format changes.
  • Docs: ok. fs.md, regenerated skills copy and PATH.md updated; pdisc green.
  • After merge: nothing required.

Non-blocking:

  • Paths are now normalised on entry, so an empty string reads as . (e.g. createDirectory("") becomes a no-op instead of an error). Consider one line in fs.md next to the new paragraph.
Review of 1234646 - approved. - Tests: ok. New group "path parameters" in std/fs/tests/files.test.trb covers String, literal and Path on natives and wrappers, plus IoError.path normalisation (native, hand-built, metadata). CI combined status success on this head (bootstrap, tier A, gates, pdisc, commit messages). - Correctness: ok. Wrappers convert once via textOf and pass the unchanged `/` text to the helpers; internal re-calls (removeDirectory, move) are idempotent. The fileCreateTemporary exception (empty text = system temp dir, Path.from("") is `.`) is sound and documented at the native. - Scope: ok. Matches #547 / step 2 of #68; return types, list/walk/absolutePath and IoError.path untouched; no callers outside std/fs. - Security/data: ok. No secrets, deps or storage-format changes. - Docs: ok. fs.md, regenerated skills copy and PATH.md updated; pdisc green. - After merge: nothing required. Non-blocking: - Paths are now normalised on entry, so an empty string reads as `.` (e.g. `createDirectory("")` becomes a no-op instead of an error). Consider one line in fs.md next to the new paragraph.
argus merged commit 877b4bdf0b into main 2026-10-28 17:32:19 +00:00
argus deleted branch loop/547-fs-into-path 2026-10-28 17:32:19 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!549
No description provided.