natives: Into<Path> parameters and a Path in IoError.path (teach the compiler, commit 1 of 2 for #68) #419

Closed
opened 2026-10-23 07:25:30 +00:00 by orion · 1 comment
Collaborator

Context

First step of #68 (PATH slice 2, the boundary). Slice 1 (std/path) and the checker condition of PATH.md section 5 are in: a receiver of the trait type Into<Path> resolves into() as an ordinary trait call (compiler/tests/conversions.test.trb), and std/fs already passes the / text form to the runtime on every system.

What is not proved is the native side: every std/fs native still has String parameters, and the lowering builds the IoError of a .Fallible native from the native's parameter named path (compiler/src/backend/c/natives.trb, the .Fallible convention). Before any std/fs signature can change, both back ends and the lowering must accept a native parameter of type Into<Path> and an IoError whose path is a Path. This issue teaches that and nothing else (commit 1 of 2 of the seed rule); the migration of std/fs is the following step of #68.

Source

  • docs/design/PATH.md section 5 (Into<Path> as a parameter type), section 6 (the boundary to the operating system, the std/fs listing) and section 8, slice 2

Goal

A native fn or native static fn may declare a parameter path: Into<Path>; the C back end passes the runtime the / text of that path (path.into().show(), converted once at the call), and the IoError a .Fallible native answers can carry path: Path as well as path: String, chosen by the declared field type.

Acceptance criteria

  • The checker, the lowering and the C back end accept a native whose parameter is Into<Path>; the runtime function it maps to still receives one torb_text (no change in runtime/)
  • The same native called with a String, a string literal and a Path argument works (the literal rule and the blanket Into give the first two, Path is Into<Path> through From<Path>)
  • A .Fallible native with an Into<Path> parameter builds its IoError with the Path of that argument when IoError.path is declared Path, and keeps building it from the String parameter when it is declared String (both forms stay valid until step 3 of #68)
  • Tests that fail without the change and pass with it: a checker or lowering test with the exact diagnostics, plus one program in tests/conformance/ that compares the interpreter and the native build over the three argument kinds and an error message that names the path (use a fixture native or an existing one that is not a std/fs signature, so std/fs stays untouched)
  • docs/design/PATH.md slice 2 gets a line saying which half is in (the native side); the status header stays "partly implemented"

Seed

Yes: changes how the lowering and the C back end read a native signature, and the compiler compiles itself with it. Two-commit rule of CLAUDE.md "Seed and breaking changes": this issue is commit 1 (teach, no std or compiler source uses the new form yet). The seed refresh stays Torben's; migrating std/fs waits for it.

Scope

  • compiler/src/semantics/checker/* only where a native signature rejects a trait-typed parameter
  • compiler/src/ir/lower/*, compiler/src/backend/c/natives.trb
  • tests under compiler/tests/ and tests/conformance/, the one PATH.md line

Out of scope

  • Any std/fs, std/io, std/process signature (steps 2 and 3 of #68), list answering List<Path>
  • runtime/ (the Windows half is already in), seed/, releases

Dependencies

None open: slice 1 and the checker condition are on main. Part of #68.

## Context First step of #68 (PATH slice 2, the boundary). Slice 1 (`std/path`) and the checker condition of PATH.md section 5 are in: a receiver of the trait type `Into<Path>` resolves `into()` as an ordinary trait call (`compiler/tests/conversions.test.trb`), and `std/fs` already passes the `/` text form to the runtime on every system. What is not proved is the *native* side: every `std/fs` native still has `String` parameters, and the lowering builds the `IoError` of a `.Fallible` native from the native's parameter named `path` (`compiler/src/backend/c/natives.trb`, the `.Fallible` convention). Before any `std/fs` signature can change, both back ends and the lowering must accept a native parameter of type `Into<Path>` and an `IoError` whose `path` is a `Path`. This issue teaches that and nothing else (commit 1 of 2 of the seed rule); the migration of `std/fs` is the following step of #68. ## Source - `docs/design/PATH.md` section 5 (`Into<Path>` as a parameter type), section 6 (the boundary to the operating system, the `std/fs` listing) and section 8, slice 2 ## Goal A `native fn` or `native static fn` may declare a parameter `path: Into<Path>`; the C back end passes the runtime the `/` text of that path (`path.into().show()`, converted once at the call), and the `IoError` a `.Fallible` native answers can carry `path: Path` as well as `path: String`, chosen by the declared field type. ## Acceptance criteria - [ ] The checker, the lowering and the C back end accept a native whose parameter is `Into<Path>`; the runtime function it maps to still receives one `torb_text` (no change in `runtime/`) - [ ] The same native called with a `String`, a string literal and a `Path` argument works (the literal rule and the blanket `Into` give the first two, `Path` is `Into<Path>` through `From<Path>`) - [ ] A `.Fallible` native with an `Into<Path>` parameter builds its `IoError` with the `Path` of that argument when `IoError.path` is declared `Path`, and keeps building it from the `String` parameter when it is declared `String` (both forms stay valid until step 3 of #68) - [ ] Tests that fail without the change and pass with it: a checker or lowering test with the exact diagnostics, plus one program in `tests/conformance/` that compares the interpreter and the native build over the three argument kinds and an error message that names the path (use a fixture native or an existing one that is not a `std/fs` signature, so `std/fs` stays untouched) - [ ] `docs/design/PATH.md` slice 2 gets a line saying which half is in (the native side); the status header stays "partly implemented" ## Seed Yes: changes how the lowering and the C back end read a native signature, and the compiler compiles itself with it. Two-commit rule of `CLAUDE.md` "Seed and breaking changes": this issue is commit 1 (teach, no `std` or compiler source *uses* the new form yet). The seed refresh stays Torben's; migrating `std/fs` waits for it. ## Scope - `compiler/src/semantics/checker/*` only where a native signature rejects a trait-typed parameter - `compiler/src/ir/lower/*`, `compiler/src/backend/c/natives.trb` - tests under `compiler/tests/` and `tests/conformance/`, the one PATH.md line ## Out of scope - Any `std/fs`, `std/io`, `std/process` signature (steps 2 and 3 of #68), `list` answering `List<Path>` - `runtime/` (the Windows half is already in), `seed/`, releases ## Dependencies None open: slice 1 and the checker condition are on `main`. Part of #68.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T13:33:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T13:33:00Z
argus closed this issue 2026-10-23 11:36:59 +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#419
No description provided.