ADR-215: What Was Left of ADR-212 §5 — insert, str::chars, a Slice’s Type, a Named Range in the Brackets, and a Copy of a View

Status: Superseded by ADR-293 — its D1-D4 are D21-D24 there Date: September 25, 2026 Target Version: Nikaia 0.0.191 Answers: the owner’s yes to the four finds ADR-212 §5 left open after ADR-213 and ADR-214 took the others Related: ADR-184 D3 (ref Array[T], a run somebody else keeps), ADR-207 D3 (a read-only String parameter is a &str), ADR-212 D3 (a range kept in a name), ADR-213 D3 (what a keeper is handed)

1. Context

  program before
a m.insert(k, v) no ledger entry: not checked, a literal key not built into the map’s text
b t.chars().rev() for a view t str::chars said -> ?, so nothing after it was checked
c ref xs[1..<3] handed to a function the slice had no type; handed to a ref Vec[i64] it was rustc’s expected &Vec<i64>, found &&[_]
d let q = 1..2 then ref xs[q] rustc: type annotations needed

And one found writing the probes for (c):

  program before
e fn copy(name: String) -> String { return name.clone() } rustc: mismatched types — the parameter is a &str (ADR-207 D3), and .clone() of a &str is the &str

2. Decisions

D1 — HashMap::insert is the write under the language below’s name.

(ref HashMap[$K, $V], key: $K, value: $V) -> $V?, keeping both. m[k] = v stays the language’s form; insert is for a program that wants the value it replaced. A text literal handed to a position the receiver binds to String — $K here — is built into text of its own, which the per-argument check did not see because it read the signature before the receiver bound it.

D2 — str::chars says what String::chars says.

Seq[char] sync ends: a view of text is walked one character at a time, from either end.

D3 — A slice is ref Array[T], a run a function can take.

A range in the brackets of a list reads a run of it, and ADR-184 D3 already named the type a declaration writes to take one: ref Array[T], &[T] below. So a list slice has that type, a text slice is a view of text, and a list’s windows and chunks hand out ref Array[$T] rather than the ref Vec[$T] ADR-212 D5 wrote for want of this. A slice fits a parameter declared ref Array[T]; so does a list, as it did. A parameter declared ref Vec[T] is still a list and still refuses a slice — in this language’s words now, since the slice has a type.

A range kept in a name slices exactly as a written one: the checker tells the emitter which index is one, and the read is the slice path (no *), so a range whose ends are both literals no longer leaves rustc an integer type to guess through an unused dereference.

D4 — A copy of std’s is to_owned below.

.clone() of a &str or a &[T] is the reference: the language below clones the pointer. .to_owned() is a copy for a view and for a value alike, so a clone call the checker resolved to a std entry (String::clone, str::clone, and the new Vec::clone) is written to_owned. A program’s own method called clone is not touched.

3. What is built

All of it, in 0.0.191: the two ledger entries and the three changed signatures, the receiver-bound literal, the slice types and the fit of a slice to a run, slice_indices and owned_copies from the checker to the emitter, and tests in crates/nikaia/tests/handed_over.rs and sequence_shapes.rs, each program run at both settings of user_parallelism.

This site is open source. Improve this page.