fs: std/fs path parameters take Into<Path> (step 2 of #68, PATH slice 2) #547

Closed
opened 2026-10-28 14:24:51 +00:00 by orion · 2 comments
Collaborator

Context

Second step of #68 (PATH slice 2, the boundary). Step 1 (#419, commit 23bfecf) taught the compiler a native parameter of type Into<Path>: the call converts the argument once (path.into().show()), the runtime still receives one torb_text, and a .Fallible native builds its IoError from that argument. std/fs still declares every path parameter as String. This issue changes exactly those parameters and nothing else: callers that pass a String, a string literal or a Path all compile and behave as before.

Source

  • docs/design/PATH.md section 6 ("std/fs answers Path values", the signature listing), section 8 slice 2

Goal

Every path parameter of the public std/fs surface (File, and the Fs operations in std/fs/src/lib.trb) is Into<Path> instead of String. Return types, IoError.path and list stay as they are; they are steps 3 and 4 of #68.

Acceptance criteria

  • In std/fs/src/lib.trb every parameter named path, to, target-as-path and the inside of the temporary-entry functions that names a file or directory is Into<Path> (the native rows open, create, readText, writeText, exists, isDirectory, createDirectory, absolutePath, list, remove, rename, copy, createSymbolicLink, symbolicLinkTarget, the private natives fileReadBytes, fileWriteBytes, fileReplace, fileMetadata, fileOwner, fileSetMode, fileCreateTemporary, and the non-native wrappers readBytes, writeBytes, read, write, writeBytesAtomically, writeTextAtomically, walk, removeDirectory, move, metadata, linkMetadata, owner, linkOwner, setPermissions, createTemporaryFile, createTemporaryDirectory). If Into<Path>? (the inside: ... ? = None parameters) is rejected by the checker, that one parameter stays String? and the diagnostic is quoted in the PR as the reason; every other parameter still changes
  • Return types are unchanged: absolutePath, list, walk, symbolicLinkTarget and the temporary-entry functions still answer String/List<String>, and IoError.path is still a String (it is built from path.into().show() in the wrappers that construct it by hand)
  • The private helpers of std/fs that split or join the text (joinedPath, directoryOf, nameOf, walkInto, copiedEntry, removedEntry) keep working on String and receive the / text of the path (.into().show() once at the entry of the wrapper); no behaviour of a result or an error message changes
  • No caller outside std/fs needs an edit; if the build shows one that does (an argument of a type that is neither String, literal nor Path), it is fixed in the same PR and listed in its body
  • std/fs/tests/files.test.trb gains tests that fail on main (compile error) and pass with the change: one operation each called with a String value, a string literal and a Path (Path.from(...)), for a read (readText), a write (writeText), a two-path operation (rename or copy) and a failure whose IoError.path is the / text of the path that was passed
  • tests/conformance/ programs that use std/fs still compare identical on the interpreter and the native build (no .expected file changes)
  • docs/standard-library/fs.md (and the doc comments with code examples in std/fs/src/lib.trb, which docs check compiles) show the Into<Path> parameter types; docs/design/PATH.md status header gets one sentence: the parameters of std/fs are in, list, IoError.path and systemPath are not; the header stays "partly implemented"
  • skills/ regenerated if the docs change requires it

Seed

No change. This step uses the form that step 1 taught; it adds no native, no syntax and no name the compiler looks up. The compiler compiles itself with std/fs, so the seed that bootstraps CI has to know the form: the newest published seed (142293fd98fc, head of seeds.txt) contains 23bfecf (checked with git merge-base --is-ancestor 23bfecf 142293fd98fc), so CI bootstraps it without a seed run. The seed refresh of the main checkout's seed/ stays Torben's and is not needed for this PR.

Out of scope

  • list answering List<Path>, absolutePath answering Path, the walkers that re-join names (step 4 of #68)
  • IoError.path becoming a Path (step 3)
  • systemPath (a new native, so its own step 2b of #68)
  • std/io, std/process, compiler/, tools/ callers beyond what compiles unchanged
  • runtime/, seed/, releases

Dependencies

Part of #68. Step 1 #419 is closed and on main. Nothing else open.

Commits

One refactor(fs) commit for the signatures, one test(fs) or docs(fs) commit for tests and docs if the PR is easier to read that way; a single commit is fine too.

## Context Second step of #68 (PATH slice 2, the boundary). Step 1 (#419, commit 23bfecf) taught the compiler a `native` parameter of type `Into<Path>`: the call converts the argument once (`path.into().show()`), the runtime still receives one `torb_text`, and a `.Fallible` native builds its `IoError` from that argument. `std/fs` still declares every path parameter as `String`. This issue changes exactly those parameters and nothing else: callers that pass a `String`, a string literal or a `Path` all compile and behave as before. ## Source - `docs/design/PATH.md` section 6 ("`std/fs` answers `Path` values", the signature listing), section 8 slice 2 ## Goal Every path *parameter* of the public `std/fs` surface (`File`, and the `Fs` operations in `std/fs/src/lib.trb`) is `Into<Path>` instead of `String`. Return types, `IoError.path` and `list` stay as they are; they are steps 3 and 4 of #68. ## Acceptance criteria - [ ] In `std/fs/src/lib.trb` every parameter named `path`, `to`, `target`-as-path and the `inside` of the temporary-entry functions that names a file or directory is `Into<Path>` (the native rows `open`, `create`, `readText`, `writeText`, `exists`, `isDirectory`, `createDirectory`, `absolutePath`, `list`, `remove`, `rename`, `copy`, `createSymbolicLink`, `symbolicLinkTarget`, the private natives `fileReadBytes`, `fileWriteBytes`, `fileReplace`, `fileMetadata`, `fileOwner`, `fileSetMode`, `fileCreateTemporary`, and the non-native wrappers `readBytes`, `writeBytes`, `read`, `write`, `writeBytesAtomically`, `writeTextAtomically`, `walk`, `removeDirectory`, `move`, `metadata`, `linkMetadata`, `owner`, `linkOwner`, `setPermissions`, `createTemporaryFile`, `createTemporaryDirectory`). If `Into<Path>?` (the `inside: ... ? = None` parameters) is rejected by the checker, that one parameter stays `String?` and the diagnostic is quoted in the PR as the reason; every other parameter still changes - [ ] Return types are unchanged: `absolutePath`, `list`, `walk`, `symbolicLinkTarget` and the temporary-entry functions still answer `String`/`List<String>`, and `IoError.path` is still a `String` (it is built from `path.into().show()` in the wrappers that construct it by hand) - [ ] The private helpers of `std/fs` that split or join the text (`joinedPath`, `directoryOf`, `nameOf`, `walkInto`, `copiedEntry`, `removedEntry`) keep working on `String` and receive the `/` text of the path (`.into().show()` once at the entry of the wrapper); no behaviour of a result or an error message changes - [ ] No caller outside `std/fs` needs an edit; if the build shows one that does (an argument of a type that is neither `String`, literal nor `Path`), it is fixed in the same PR and listed in its body - [ ] `std/fs/tests/files.test.trb` gains tests that fail on `main` (compile error) and pass with the change: one operation each called with a `String` value, a string literal and a `Path` (`Path.from(...)`), for a read (`readText`), a write (`writeText`), a two-path operation (`rename` or `copy`) and a failure whose `IoError.path` is the `/` text of the path that was passed - [ ] `tests/conformance/` programs that use `std/fs` still compare identical on the interpreter and the native build (no `.expected` file changes) - [ ] `docs/standard-library/fs.md` (and the doc comments with code examples in `std/fs/src/lib.trb`, which `docs check` compiles) show the `Into<Path>` parameter types; `docs/design/PATH.md` status header gets one sentence: the parameters of `std/fs` are in, `list`, `IoError.path` and `systemPath` are not; the header stays "partly implemented" - [ ] `skills/` regenerated if the docs change requires it ## Seed No change. This step *uses* the form that step 1 taught; it adds no native, no syntax and no name the compiler looks up. The compiler compiles itself with `std/fs`, so the seed that bootstraps CI has to know the form: the newest published seed (`142293fd98fc`, head of `seeds.txt`) contains 23bfecf (checked with `git merge-base --is-ancestor 23bfecf 142293fd98fc`), so CI bootstraps it without a seed run. The seed refresh of the main checkout's `seed/` stays Torben's and is not needed for this PR. ## Out of scope - `list` answering `List<Path>`, `absolutePath` answering `Path`, the walkers that re-join names (step 4 of #68) - `IoError.path` becoming a `Path` (step 3) - `systemPath` (a new native, so its own step 2b of #68) - `std/io`, `std/process`, `compiler/`, `tools/` callers beyond what compiles unchanged - `runtime/`, `seed/`, releases ## Dependencies Part of #68. Step 1 #419 is closed and on `main`. Nothing else open. ## Commits One `refactor(fs)` commit for the signatures, one `test(fs)` or `docs(fs)` commit for tests and docs if the PR is easier to read that way; a single commit is fine too.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-28T21:22:25Z

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-28T21:22:25Z
Author
Collaborator

[loop:torbscript] implement: PR #549 opened (3 commits: refactor/test/docs; all path parameters of std/fs are Into, local torb test std/fs/tests/files.test.trb 38 passed on the nightly toolchain; one deviation: private native fileCreateTemporary keeps a String path because the empty text means the system temp directory and Path.from("") is ., reasoning in the PR), next: waiting (CI on PR and merge gate). Worker usage: one Sonnet 5.5 implement worker, token count not metered in the worker session.

[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/549 opened (3 commits: refactor/test/docs; all path parameters of std/fs are Into<Path>, local `torb test std/fs/tests/files.test.trb` 38 passed on the nightly toolchain; one deviation: private native `fileCreateTemporary` keeps a `String` path because the empty text means the system temp directory and `Path.from("")` is `.`, reasoning in the PR), next: waiting (CI on PR and merge gate). Worker usage: one Sonnet 5.5 implement worker, token count not metered in the worker session.
argus closed this issue 2026-10-28 17:32:19 +00:00
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
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#547
No description provided.