Skip to content

v0.6.1

Latest

Choose a tag to compare

@github-actions github-actions released this 17 Oct 01:21
· 82 commits to main since this release
v0.6.1
6a446f7

Hew v0.6.1

Hew 0.6.1 adds reusable generic closures, typed configuration embedded at compile
time, deeper machine hierarchies and confinement around supplied services. It
also improves actor deadlines and native execution, and updates the TLS library
to address upstream security advisories.

Upgrading from 0.6.0

  • Upgrade communicating peers together. The wire protocol changes from v2 to v4;
    earlier versions are rejected explicitly. Put shared protocol declarations in
    imported modules with portable dotted owner paths, rather than separate
    executable roots. Calls now carry canonical declaration identities and
    inherited request budgets, with no numeric handler-hash fallback.
  • Keep each node's identity file when upgrading. Set NodeConfig.key to a
    non-empty path before calling Node.start(config); NodeConfig.at(address)
    leaves that field empty. Startup reads an existing key or creates one when
    absent. Keep the file private and back it up: replacing it changes the
    node's identity and the credentials its peers must pin. A wrong-size TCP
    key file is refused rather than regenerated.
  • Use NodeTransport.Tcp or NodeTransport.QuicMesh for distributed nodes,
    with configured peer credentials. The legacy HEW_TRANSPORT=quic selector
    is still recognized in 0.6.1, but cannot supply the credential binding that
    authenticated node startup requires. It is not an unauthenticated mesh
    option. std.net.quic remains the separate QUIC socket API.
  • Review computed machine transitions. A computed _ target exits the full
    active branch, evaluates the body once, then enters the returned branch,
    including same-leaf and sibling returns. Use named targets when a transition
    should retain shared ancestors and run hooks only along the changed branch.
  • Update TLS-dependent applications. Hew 0.6.0 bundles rustls 0.23.45; this release
    updates it to 0.23.46, addressing
    RUSTSEC-2026-0346,
    0347,
    0348 and
    0349.
  • Packages using the new language features can declare hew = ">=0.6.1" in
    hew.toml.

Generic helpers

Generic closures declare type parameters after the opening pipe, as in
|<T: Eq> left: T, right: T| -> bool { left == right }. Store or return them with
a type such as fn<T: Eq>(T, T) -> bool. Callable qualifiers use the usual
fn[qualifiers]<T: Bound>(T) -> R spelling. Calls infer concrete types or accept
an explicit type list. All instantiations share the same captured state; mutable
and once-only invocation rules apply across the whole closure value.

Generic functions can constrain associated-type projections with
where I.Item: Display or where <I as Iterator>.Item: Display. These bounds
carry through imported helpers and generic closures on native and sandbox
execution, including equalities such as Iterator<Item = T>.

Trait implementations obey shared package ownership and overlap rules across
native compilation, virtual package inputs and editor analysis. Generic and
blanket implementations use the same checked declaration identities.

Compile-time data and generation

embed!(path) reads JSON, YAML or TOML at compile time and checks it against the
expected concrete type and its ordinary serialization schema. Generated programs
construct ordinary values without decoding the file at runtime. Repeated uses
retain independent value semantics. Invalid data names its input file and field
path; embedded collection keys with custom equality are rejected. Native and
sandbox execution share these semantics, including target-specific integer
range checks.

location!() produces an ordinary SourceLocation constant. Ordinary constants
also support records, enums, tuples and collections, including record updates
and vector spreads, through the same checked value representation.

Declarative macros preserve definition and caller binding contexts across native
and sandbox compilation. Function and method attribute macros compose in stacks;
the CLI, editor and browser analyzer use the same expansion pipeline. Declared
generators run through hew generate, with tracked inputs and check mode.

Machines and actor calls

Composite machines support deeper nesting and recursive initial-child descent.
Child rules precede the nearest ancestor's rules, with guarded fallback. Parallel
regions and history states remain unavailable.

Actor interceptor chains preserve caller identity, refusal and cleanup
behaviour. A refused call has no response value.

Actor calls that wait for a reply inherit the earliest scope and incoming
request expiry.
Expired queued calls never start. A claimed handler remains owned by its actor,
while its nested calls return TimedOut once the inherited budget is exhausted.
Caller expiry abandons the reply and cannot undo a remote mutation. Local native
and sandbox execution share that boundary; distributed asks carry relative
budgets and authenticated best-effort withdrawal of queued requests. Caller
expiry and cancellation remain responsive when another sender or a peer stalls
transport progress. Required ownership cleanup remains shielded from the
abandoned request deadline.

Confinement with supplied services

Actors and ordinary functions can use #[confined] to reject transitive ambient
authority acquisition and opaque native escapes. Opened std.fs.ReadFile and
WriteFile resources provide directional access to one file, supplied once at
construction. Ordinary helpers, captured callables, trait implementations and
required cleanup preserve that boundary. Generic libraries can be checked in
isolation; concrete calls and constructions discharge their supplied-service
authority obligations. Incomplete authority summaries, including erased
generator execution or cleanup, are refused conservatively.

std.fs.ReadDir and WriteDir extend this wiring to a directory tree. Their
operations accept relative child paths, subdir narrows the root, and
open_read or open_write opens an independently owned directional file.
Contained relative symlinks work; absolute paths, parent escapes and escaping
symlinks are refused. Opened files and narrowed roots remain usable after the
parent resource closes. An opened root follows its directory if renamed; some
hosts refuse renaming an open directory. Acquiring a directory is ambient
authority and remains unavailable inside a confined component.

The same domain interfaces support in-memory services on the browser VM. File
and directory resources run natively. Cross-node capability delegation remains
separate; confined code continues to refuse remote acquisition.

Runtime and native execution

Inbound distributed actor asks wait through scheduler readiness instead of one
blocked OS thread per request. Pending replies are bounded per destination actor
incarnation, so a slow service does not occupy unrelated services' ask capacity.

Native coroutine lowering uses LLVM's switched-resume machinery for frame
splitting and optimization. Proven synchronous callables avoid child coroutine
states; implicit resource cleanup participates in source suspension effects.
Scalar vector replacement and last-use actor payload transfers avoid redundant
allocation and reference-count work.

Function values avoid redundant allocations during construction and release.
String comparisons in the browser VM use the same UTF-8 ordering as native
programs, including characters outside the Basic Multilingual Plane.

Compiler fixes

Large applications containing ordinary records and enums no longer repeatedly
trace those values for scoped tasks when their types cannot hold tasks or
captured callbacks. Types that can carry either still receive the lifetime
checks, including positional records that wrap a callback.

Parent-relative imports such as import "../worker.hew" now compile when the
imported module defines a generic actor; these imports previously triggered a
compiler panic.

Known publishing limitation

hew publish can fail with E_PUBLISH_MISSING_INPUT when a package uses
installed package dependencies. It incorrectly requires those dependency files
inside the package's own archive. Installing and running already-published
packages remains supported.

Platforms and next steps

Native SDKs target Linux, macOS, Windows and FreeBSD. Install the SDK for your
platform, or use the browser playground for sandbox execution. The
language specification
provides the syntax and behavioural contracts; the
full changelog
covers the changes since 0.6.0.