Nocter v0.11.0 Release Notes
Download nocter-v0.11.0-arm64-darwin.tar.gz
Nocter v0.11.0 makes generic contracts, associated types, implementation declarations, destruction, and static opaque results one coherent compile-time model. It also removes the remaining native cleanup restriction for whole move-only aggregates in control flow.
Generic Contracts and Associated Types
Generic parameters contain names only. All constraints use a declaration-wide where clause:
func duplicate<T>(value: T): T where copy T {
return value
}
func collect<I>(source: I): Vec<I.Item>
where I: Iterator {
return source.to_vec()
}
copy is an intrinsic compiler-owned requirement rather than an interface or type modifier. Interfaces can declare required associated types, conformances bind them exactly once, and Self.Item, I.Item, associated bounds, and equality predicates resolve through one declaration identity. Iterator APIs no longer need courier type parameters solely to transport item types.
Explicit Declaration Roles
Nocter now separates the operations that older impl syntax overloaded:
instance Vec<T> {
pub method &self.capacity(): usize { ... }
}
conform Iterator for VecIntoIter<T> {
type Item = T
method &+self.next(): T? { ... }
}
destruct Vec<T>(&+self) {
...
}
instance defines behavior for existing values, conform proves an interface contract, and destruct defines the unique destruction program for a type family. Declaration type patterns infer their binders. Concrete refinements use where T = Concrete, so the language has no second binder list or specialization ranking convention.
Path-Sensitive Destruction
Ownership-valid whole-aggregate moves, explicit drops, and reinitialization now lower through branches, matches, loops, short-circuit conditions, optional and fallible paths, and early exits. Only destructor-bearing move-only locals that cross path-sensitive control flow acquire a runtime live flag. Straight-line values retain static zero-cost cleanup, and every executed path destroys each remaining value exactly once.
Static Opaque Results
A body-bearing callable can publish one interface without exposing its concrete result type:
pub func lines(text: &str): some Iterator<Item = &str> from text {
return LinesIter.new(text)
}
some Interface is static abstraction. The compiler proves one concrete witness per declaration and specialization, but callers see only the advertised interface and associated bindings. The witness determines layout, ABI, static dispatch, and destruction without a vtable, box, metadata field, implicit allocation, or dynamic dispatch. Opaque values are move-only at the public boundary, compose with ?, !, and from, and retain ordinary storage-loan checking.
The standard str.lines() method uses this contract while the concrete iterator types remain available for APIs that need nameable state.
Tooling
The formatter, AST JSON, diagnostics, hover, completion, inlay hints, signature help, semantic tokens, definition, references, and rename understand the new generic requirements, associated identities, declaration kinds, and opaque contracts. Editor presentation never reveals an opaque witness or invents inferred source syntax.
Compatibility and Limits
Code using inline generic bounds, impl, impl for, instance-owned destruction members, or explicit declaration binder lists must migrate to where, instance, conform, independent destruct, and inferred declaration patterns. No compatibility grammar is retained.
Static opaque results are return-only and advertise one interface. This release does not add runtime interface objects, dynamic dispatch, named opaque aliases, opaque fields or parameters, multiple advertised interfaces, generic associated types, specialization ranking, partial field moves, unwinding, a stable cross-version ABI, or another host or native target. The supported host and target remain arm64-darwin.
Qualification
The v0.11.0 candidate passed clean and incremental complete repository verification, with 3,527 tests per run plus formatting, documentation generation, and warnings-denied Clippy. Two independently created archives had equivalent extracted content.
The published arm64-darwin archive is 3,651,844 bytes with SHA-256 d2e1e11cdfdf666b0d3661cf44ad91fb5ffc92bd81bbb853245268a6288eedbb. A fresh extraction without environment configuration passed package creation, locked/offline check and native test, deterministic graph generation, run, explicit build, direct Mach-O execution, and the complete LSP initialize, initialized, shutdown, and exit lifecycle.
The public download and version history are available from the release index.