Open and answer this issue on GitHub.
libraries, compiler, blocked · opened 2026-10-05 · updated 2026-10-06 · 2 comments
fs::map returns an fs::Mapped. A grammar entry takes one (Measurements::file(data) in examples/1brc.nika), but code that wants the text itself has no spelling that compiles. Each of these three passes the checker, and the build then fails in rustc, about generated code (Part III C.1):
use std::fs
fn main() throws {
let data = fs::map("m.txt", fs::Root::Anywhere) catch { return }
let a = data[0..<7] // rustc: the trait bound `Mapped: Get<_>` is not satisfied
let b = data.deref() // rustc: no method named `deref` found for struct `Mapped`
let c: ref String = data // rustc: mismatched types
}
The ledger has fs::Mapped::deref. The emitted call needs std::ops::Deref in scope, or the method written as &*data.
Hand-tuning examples/1brc.nika: a byte-level parser over the mapping had to fall back to fs::read_to_string, which copies the file.
ref String wherever a view of text is wanted. Either write the deref, or refuse in the language’s words with a way out. Today it is neither.data[a..<b] on a Mapped a slice of its text, as it is on a String.fs::read_to_string.Two more of the same kind, found while preparing #453. Both pass the checker and fail in rustc:
let raw = fs::read("m.txt", fs::Root::Anywhere)
let first = raw[0] // rustc: the trait bound `Bytes: Get<{integer}>` is not satisfied
let s = "Hamburg;12.3"
let at = s.find(";") ?? 0 // reaches Rust's `str::find`, which no ledger describes
let n: i64 = at // rustc: mismatched types (`usize`, not `i64`, ADR-285 D1)
str::find is not in std.contracts, so the call fails open into Rust’s method with Rust’s types. What find and Bytes’ content access should be is #453’s decision. Until that decision, both lines should be refused in the language’s words: NK1210’s rule for a method of a number std does not describe, applied to text and Bytes too.
Generated by Claude Code
The three items of “To build” are built in 0.0.512 (c8ff4a7). Each of the three lines now compiles and reads the mapping, with the same output as fs::read_to_string.
data[a..<b]: index::Get for fs::Mapped slices its text, by the same rule as a String’s.data.deref(): Mapped now has deref as a method of the type itself. The lowered call no longer needs std::ops::Deref in scope.let c: ref String = data: a let that declares a view a container derefs to now lends the container (lent_lets, written &data). Before, it was handed over, so data was gone after the line (NK2105) and rustc refused the line. Handing data to a ref String parameter already worked.Test: defects_found_running::a_mapped_file_is_read_as_text. Every bench and example lowers byte for byte as before.
Still open, from the comment above: raw[0] on Bytes, and text’s find, which no ledger describes.
The comment proposes refusing both with NK1210’s rule, extended from numbers to text and Bytes, until #453 decides. That would refuse every text or Bytes method std does not describe. Programs that use one today and reach rustc would become refusals in the checker.
Question for the deciding session: should NK1210 be extended this way now, or should this wait for #453’s decision on find and Bytes’ content? Until it is answered, I’m leaving this issue open and building nothing further here.
Generated by Claude Code