v1.0.0
LatestMajorThe first stable release. The compiler is self-hosted, the standard library is written entirely in Cryo, and the public surface is frozen under semver.
Compiler
- Self-hosted compiler with an LLVM 20 backend. Every release is built
by the previous release;
make selfhost-checkruns a 3-round (6-stage) byte-identical IR check that gates every push tomain. - Type system: static, monomorphic generics with
wherebounds, no implicit conversions. Local type inference onconst/mutbindings: a binding adopts its initializer's concrete type, so an explicit: Tis required only when there is no initializer to infer from (or to widen the declared type).typeof(expr)in type position. - Traits: trait declarations with default methods; impls on primitives,
structs, unions, and enums; coherence checks (a trait may be implemented
at most once per type) enforced uniformly within a file and across
modules, keyed on the import-resolved impl head so generic traits
(
From<i8>vsFrom<i16>), generic targets, andwhere-bounds are all distinguished. - Associated types. A trait may declare an associated type
(
type Item;) and refer to it by projection (This::Iteminside the trait,I::Itemoff a generic parameter). Each impl binds it positionally (implement trait Iterator<i32> for X- sugar forIterator<Item = i32>, available when the trait has no generic params of its own) or with the explicit body form (type Item = i32;). Two diagnostics enforce the binding rules:E0309(a declared associated type left unbound by an impl) andE0310(an associated type bound positionally on a trait that also has generic params - use the explicit body formtype Out = ...;instead). Declaration-site bounds on an associated type (type Item: Copy;) are enforced against each impl's concrete binding (E0306). Opaqueimplement Iterator<T>bindings now cross-check<T>against the iterator's actualItem(E0200on a category-level mismatch). Seedocs/cryo.mdsection 10.5. - Trait objects:
virtual &T,virtual mut &Tandvirtual T*hold a value of any type implementingTwith a table of that type's methods, and a call on the object goes through the table. The table holds the methods ofT's supertraits too, a trait with type arguments has objects (virtual mut &Iterator<i32>), and a method a table cannot hold is refused only where it is called. An object satisfies a bound of its own trait and of each supertrait, so it can be passed to generic code. Seedocs/cryo.mdsection 10.7. - Enums: algebraic enums with explicit discriminants and discriminant
base type (
type enum X : u8 { ... }), exhaustive match enforcement on enum subjects. - Pattern matching: literal, identifier-binding, wildcard,
enum-destructure (including nested sub-patterns such as
Some(Some(n))andBranch(Leaf(x), r), with discrimination on literal payloads likeSome(5)), range patterns (a..band the explicita..=b; both are inclusive in pattern position), or-patterns (a | b | c), and guard clauses (pattern if (cond) => ..., checked after the pattern matches with a false guard falling through to the next arm). Exhaustiveness accounts for nested coverage (Wrap(A)+Wrap(B(n))coversWrap). - Ownership:
CopyandDroptraits with automatic recursive drop glue through struct fields, enum payloads, and container elements.- Fatal use-after-move (E0452), partial-move out of owning aggregate (E0453), and loop-carried move detection.
![sink]attribute for methods that consume the receiver.
- Layout directives:
![repr(...)]and![align(N)]honored per generic instantiation. - ABI: SysV-amd64 lowering with eightbyte classification, DirectPair,
sret,byval, and<2 x float>packing for both extern-C and Cryo-internal calls. - FFI:
extern "C"functions, variadic functions viaVaArgs::new(...), the![link]directive for extern symbols. - Operators:
?error propagation,|>pipeline,??null-coalescing,T?optional-type sugar (desugars toOption<T>),a..b/a..=brange expressions (desugar toRange::new/RangeInclusive::new; valid in any expression position, looser than arithmetic). - f-strings (
f"...{expr}...{expr:?}..."): string interpolation. The parser desugars each f-string into a chain ofstd::fmt::interpbuilder calls that produce an ownedString;{expr}formats the value throughDisplayand{expr:?}throughDebug(so it works for any type that implements them, includingOption/Result/Array). Embedded expressions are full expressions (f"{a + b}");{{/}}are literal braces.std::fmt::interpis auto-imported into any module that uses an f-string. The printf-styleprint/println(C%d/%sspecifiers, variadic, not type-checked) remain available for raw formatted output. for (x in iter)iteration: the parser desugars toloop { match (iter.next()) { Some(x) => { ... } None => break; } }, evaluating the scrutinee exactly once. The scrutinee may be anyIterator(stdlibRange<T>/RangeInclusive<T>or anyimplement trait Iterator<T>), a range literal (for (i in 0..n)), an iterable exposingiter()(Array<T>,Slice<T>), or a fixed-size arrayT[N](viewed as aSlice<T>).- Lambdas and closures:
(params) -> Ret { body }function literals. Non-capturing lambdas compile to anonymous function pointers; capturing lambdas overCopybindings (i32/u64/bool/char/references and any![derive(Copy)]type) compile to a synthesised anonymous closure struct with a__call__method. Both forms call directly with zero overhead. Closures bound to a(Args) -> Ret-typed parameter are delivered via per-call-site receiver specialisation, so the body dispatches through__call__without an indirect call; that specialisation is wired for non-generic free functions only, so a capturing closure passed to a generic function, a method, or a scope-resolution call is E0458 (non-capturing lambdas are function pointers and bind anywhere). Generic type-parameter inference from function-typed arguments (opt.map(lambda)infersU). - Modules:
_module.cryoaggregators,public/privatevisibility, import cycle detection. async/await.asyncfunctions, methods, and trait methods are compiled into state machines, andawaitmay appear anywhere an expression may appear - in a condition, a loop body, an operand of a larger expression, amatchsubject, an arm body, and an arm guard.async function mainis renamed out of the entry-point slot and driven on anExecutorscoped to the program. A future is an ordinary movable struct with no hidden allocation and no pinning discipline, which the language buys by rejecting a reference held live across a suspend (E0455); owned values are carried across it for you. Seedocs/cryo.mdsection 18.
Build system
- New build-directory layout. The final artifact is hoisted to the
root of the build directory -
build/<name>for an executable,build/lib<name>.afor a library - so it runs asbuild/<name>regardless of profile. All intermediates live under a visible, per-profile cache tree (build/target/<profile>/) grouped by package origin: the standard library (std/), the local project (local/), and one subtree per third-party dependency (<depname>/), each holding its owndeps/*.oandir/*.ll. The combined IR dump isbuild/<name>.ll. (Breaking for tooling that hardcodedbuild/bin/,build/obj/, orbuild/.cryo/.) - Build manifest. A successful build writes a per-profile
build/target/<profile>/build-manifest.json(schema v2) recording the profile, target type/triple, optimization level, debug-info and emit-llvm flags, the linked stdlib archive, the[link]lists, every source module (namespace + path + origin/kind + object + size), and the input fingerprint. - Build profiles.
release(O2, no debug info; the default) anddebug(O0 + DWARF), selectable with--release/--dev/--profile=NAME, or[profile] default = "..."in cryoconfig. Each profile keeps its ownbuild/target/<profile>/cache. An explicit[compiler] optimizeor--opt-level=Nstill overrides the profile's level;-gforces debug info. - Incremental builds.
cryo buildnow skips the entire compile+link when no input changed (sources, resolved knobs, the compiler binary, or the linked stdlib) and the artifact still exists, printing<name> is up to date. The fingerprint is content-based and keyed per target.--no-incrementalforces a full rebuild. (Whole-build granularity is sound under Cryo's whole-program monomorphization; per-module reuse is future work, and the manifest already carries per-module hashes for it.)
Standard library
alloc:Allocatortrait,GlobalAlloc,Arena,Pool,Box<T>,Rc<T>,Arc<T>(all allocator-generic).collections:Array<T>,String,HashMap<K,V>,HashSet<T>,Pair<A,B>,Slice<T>,Str.core:Copy/Drop/Clone/Eq/Ord/Hash/Default/From/Into/TryFrom/TryInto/Display/Debug/FmtWrite/Iteratortraits;Option<T>,Result<T,E>, and the catch-allErrorstruct (there is no unifyingErrortrait — each module defines its own precise error type).core::iter:Iteratorwith an associatedtype Item(one requirednext() -> Option<This::Item>); the legacy generic-param formIterator<T>remains accepted as positional sugar forIterator<Item = T>in impls,where I: Iterator<T>bounds, andimplement Iterator<T>opaque returns. Default consumerscount/fold/for_each/any/all/findand lazy combinator adapters.take(n)/.map(f)/.filter(pred)/.chain(other)/.enumerate()/.zip(other)(returningTakeIter/MapIter/FilterIter/ChainIter/EnumerateIter/ZipIter);f/predmust be non-capturing, since the adapters are methods and a capturing closure may only be passed to a non-generic free function (E0458 - seedocs/cryo.mdsection 2.5 for the full boundary)..enumerate()yieldsPair<u64, Item>,.zip(other)yieldsPair<Item, B>and stops at the shorter side (Pairis the element type so the adapters stay monomorphization-friendly). Combinators chain freely (r.take(n).map(f).filter(p),r.chain(b).map(f),a.zip(b).count(), longer mixed chains) and feed.count()/.fold(..)/for (x in ..). The adapters resolve on any concreteIteratorreceiver, including a user struct thatimplementsIterator(mut c: Counter = ...; c.take(3).map(f)), not just stdlib iterators; bind an adapter to a concrete-typed local (mut z: ZipIter<.., ..> = a.zip(b)) or chain on the expression directly when you need a named local.collections::array::from_iter(it)collects into anArray<T>(a free function, fixed by the expectedArray<T>at the call site).io:Read/Writetraits with defaultread_all/read_byte/read_line/read_to_end/write_all;Stdin/Stdout/Stderr/BufReader<R>/BufWriter<W>/LineWriter<W>.fs: files (read/write/read_to_string/open/create/seek/copy) and whole-path operations (remove_file,rename,create_dir/create_dir_all,remove_dir/remove_dir_all,read_dir,canonicalize) overPath/PathBuf;metadata/symlink_metadata/exists/is_file/is_dirbacked bystat/lstat/access.future: the async runtime -Future/Poll/Context/Waker; a worker-poolExecutorwithspawn/JoinHandleandblock_on(under--panic=unwind, acatch_unwindboundary at every poll keeps one panicking task from taking a worker down with it); a readiness reactor overepollon Linux and\Device\Afd+ IOCP on Windows;Sleeptimers; a blocking thread pool for work no reactor can drive; and thejoin/try_join/select/timeoutcombinators. Cancelling is a plain drop - releasing a combinator disarms its timer and releases its I/O registration.net:TcpStream,TcpListener,UdpSocket,IpAddr/IpV4Addr/IpV6Addr,SocketAddr;dnsname resolution;tls(OpenSSL) withhttpson top;ws(RFC 6455) over any async transport. HTTP/1.1 server with keep-alive and read timeouts, HTTP client, router with route registration. HTTP/2 (net::http2): HPACK (RFC 7541), framing (RFC 7540), h2c client + server over any stream, generic over the transport. Every operation that waits isasyncand parks on the reactor; there is no blocking socket API. A future that needs a buffer owns it for the duration and hands it back on completion, because a future moves between polls and a borrowed caller-frame buffer would be written through a stale address.json: parser and serializer forJsonValue/JsonObject/JsonNumber; round-trip clean.process:Command/Child/ExitStatusviafork + execve;spawn/status/output/wait/try_wait/kill/send_signal, plus the async spellingsChild::join,Command::collect, andCommand::run. A captured pipe is drained byPipeDrain, andcollectdrainsstdoutandstderrconcurrently - draining one to EOF first deadlocks a child that fills the other pipe's buffer meanwhile.env:args(),var,set_var,remove_var,process_exit.sync: a genericAtomic<T>(T=u8/u32/u64/i32/i64/boolean, dispatched at compile time viastatic match),MemoryOrder,fence,compiler_fence,Mutex<T>,RwLock<T>,CondVar,Once,Barrier.Send/Syncauto-derive with call-site enforcement.thread:ThreadLocal<T>viapthread_key; OS threads viaspawn/try_spawn/JoinHandle<T>(returns the body's value onjoin),spawn_with_attr, scoped threads (thread::Scope),current/yield_now/sleep/sleep_ms. Channels insync::mpsc(channel,Sender,Receiver).Builderfor configured spawns (stack_size,name;spawn/try_spawn).math:square_root,cube_root,power,sine/cosine/tangent,natural_log/log_base2/log_base10/exponential,absolute(f64) /absolute_f32,abs_i32/abs_i64,is_nan/is_infinite/is_finite,hypot.time:Duration(normalized seconds + sub-second nanos; built and read in seconds/millis/micros/nanos;add/saturating_sub,Eq/Ord),Instant(monotonic clock -now/elapsed/duration_since),SystemTime(wall clock -now/duration_since_epochfor a Unix timestamp), andsleep(Duration). Differences saturate at zero.random:Rng, a fast non-cryptographic xoshiro256** generator seeded deterministically (from_seed) or from the OS (from_os):next_u64/next_u32/next_bool/next_f64, unbiasedbelow(bound)/range_u64(lo, hi), andfill_bytes.secure_bytes(buf, len)pulls cryptographically secure bytes from the kernel CSPRNG (getrandom).fmt:Display/Debug/FmtWritetraits,Formatter<W>,print/println/eprint/eprintln,format_to_string,format_debug_to_string, floating-point formatting.test: thecryo testframework -![test],![ignore],![should_panic],expect_*assertion helpers.ffi:CStr/CString/NulError;libcbindings (~2k LoC); syscall layer (~2k LoC).
Tooling
cryoCLI subcommands:build,run,test,check,init,fetch,update,raw,demangle,version,help.cryoconfigpackage format with[project],[compiler],[dependencies], optional[[bin]]and[lib]sections. Git-backed dependencies (git = "..."withversion/tag/branch/rev),cryoconfig.locklockfile written bycryo fetch, content-addressed cache under$CRYO_HOME/$XDG_CACHE_HOME/$HOME/.cache.- Language Server (
bin/cryolsp): hover, go-to-definition, completion (member + scope-resolution with trigger characters.and:), semantic tokens, code actions, code lenses, push diagnostics. - CryoAnalyzer VS Code extension: custom
cryo-diagnostic:virtual document scheme with themed rendering, code-lens/code-action wiring, LSP server auto-discovery. - CI:
make cryo+ smoke-test +make teston every PR and push;make selfhost-check(stage-3 == stage-4 byte-identity) on every PR and push as well.
Diagnostics
- Over 200 defined error codes (in the E0000-E0999 range) with source-span underlines, fix suggestions, and machine-applicable quickfixes where applicable.
- ANSI color rendering respecting
NO_COLOR/FORCE_COLOR/CLICOLOR_FORCEwithisatty(2)fallback. - Quickfix system covering literal coercions (E0218/E0200), parser punctuator misses (E0100), undefined-type "did you mean" suggestions (E0203), and use-after-move move-site anchors (E0452).
Examples
Fourteen worked examples under examples/, covering hello-world,
fizzbuzz, recursion, structs and methods, Array<T> ownership, file
I/O and HashMap, traits with where bounds, 2D simulation,
std::json parsing, recursive-descent parsing, an HTTP server,
stdin-driven interactive I/O, capturing closures, and OS threads with
thread::spawn / JoinHandle / mpsc channels.
Target triples
Verified end-to-end - compile, link, run, and a self-host byte-identity gate
(make selfhost-check) - on x86_64:
x86_64-*-linux-gnu- native host builds; the canonical dev/CI host.x86_64-pc-windows-gnu- native Windows host builds and Linux->Windows cross-compilation via the mingw-w64 toolchain: Win64 ABI, COFF objects,.exelinking, and a native 6-stage self-host fixed point.
The host C toolchain (header preprocessor + linker) is auto-detected
(clang-20 -> clang -> gcc -> cc) and the standard library is auto-located
relative to the cryo binary, so a stock toolchain needs neither CRYO_CC
nor CRYO_STDLIB.
Known limitations (deferred to post-1.0)
These are not bugs against 1.0 - the language deliberately ships
without them and the grammar reserves the relevant syntax. See
docs/cryo.md section 21 for the
authoritative list.
- Macros / user-defined
![attr]directives. - macOS / Darwin targets (no Mach-O backend or toolchain wiring yet). See Target triples above for the supported set.
where T: Ord + Clone, U: HashConstrains generic parameters to types that implement the listed traits, which is what makes those traits' methods callable on T. Bounds on one parameter join with +; parameters separate with ,. A where on a single method narrows the type's parameter for that method only.
const name: Type = value;An immutable binding: it cannot be reassigned after initialisation. The annotation may be omitted when an initialiser is present - the binding takes the initialiser's concrete type, inferred locally. Mutability is opt-in through mut.
mut name: Type = value;A mutable binding, reassignable after declaration - mutability is opt-in, const is the default. At module level it declares mutable global state. Before & it marks an exclusive reference or receiver instead.
typeof(expr)The static type of an expression, usable anywhere a type is expected: bindings, pointer and optional wrappers, generic arguments, as targets. The expression is type-checked but never evaluated.
type trait From<T> {
static from(value: T) -> This;
}type Name = Existing;A type alias: a new, transparent name for an existing type - the two are interchangeable everywhere. Aliases may be generic: type StringResult<T> = Result<T, string>;.
type ItemThisThe implementing type, inside a trait or implement body. other: &This in a trait method is a reference to whichever type implements it; This::Item names an associated type.
implement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referencetype trait Iterator {
type Item;
next(mut &this) -> Option<This::Item>;
count(mut &this) -> u64;
fold<Acc>(mut &this, initial: Acc, f: (Acc, This::Item) -> Acc) -> Acc;
for_each(mut &this, f: (This::Item) -> void) -> void;
take(this, n: u64) -> TakeIter<This>;
skip(this, n: u64) -> SkipIter<This>;
map<B>(this, f: (This::Item) -> B) -> MapIter<This, B>;
filter(this, pred: (&This::Item) -> boolean) -> FilterIter<This>;
chain<J>(this, other: J) -> ChainIter<This, J>;
// … 7 more
}implement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencetype Item = i32;type Out = ...;function name(count: i32, args...)A variadic parameter: the trailing bucket receives any number of further arguments with C's calling convention, so the function stays ABI-compatible with the printf family. Wrap the bucket in VaArgs to read typed values from it.
type Item: Copytype trait Copy {}Types whose values can be duplicated by a bitwise copy. Integers, floats, pointers, and pure-POD structs qualify; anything that owns resources (heap storage, file handles, refcount) does not.
std::core::markertype parameter Tvirtual &Trait
virtual mut &Trait
virtual Trait*Makes a trait object: a value of any type implementing the trait, held with a table of that type's methods for it, so code taking one is compiled once for every implementing type. The three forms borrow the value, borrow it mutably, or point at it. Written on anything but a trait it is refused (E0316); written on a method, it is E0117.
language referencemut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type enum Name {
Unit,
Payload(T),
Named { x: i32 },
}An algebraic data type. Variants may be bare or carry a tuple or struct payload, and a match on an enum must cover every variant. Name::Variant names a variant; methods are added with implement enum Name { ... }.
type enum X : u8Option::Some(T)start..endA half-open range - start up to but excluding end - and sugar for Range::new(start, end): an iterator usable in for, and an ordinary value anywhere else. It binds looser than arithmetic, so a..b + 1 is a..(b + 1).
start..=endAn inclusive range - start through end - and sugar for RangeInclusive::new(start, end). Also a match pattern: 1..=5 => { ... }.
if (condition) { ... } else if (condition) { ... } else { ... }Branches on a parenthesised boolean condition. Bodies are always braced; there is no single-statement form. Used as an expression, both arms are required and must produce the same type: const sign = if (n < 0) { -1 } else { 1 };.
pattern => { body }Separates a match arm's pattern from its body. Arms do not fall through.
extern function exit(code: i32) -> void;
extern "C" {
function puts(s: string) -> i32;
}Declares a function whose body the linker supplies - typically a C library symbol. The compiler trusts the Cryo signature; keeping it in step with the real C signature is on you.
language referencetype struct VaArgs {
ptr: void*;
}Single-pointer wrapper over the active va_list. ptr is the raw va_list pointer - the args identifier the compiler binds in a variadic body.
static VaArgs::new(va: void*) -> VaArgsWrap a variadic body's args bucket: VaArgs::new(args). va is the raw va_list pointer the compiler binds for the args... parameter.
type struct Range<T> {
start: T;
end: T;
}static Range::new(start: T, end: T) -> Range<T>type struct RangeInclusive<T> {
start: T;
end: T;
exhausted: boolean;
}static RangeInclusive::new(start: T, end: T) -> RangeInclusive<T>(parameter) expr: ?type struct String<A = GlobalAlloc> {
buffer: RawBuffer<u8, A>;
length: u64;
}String: owned, heap-allocated, length-typed UTF-8.
std::collections::stringtype trait Display {
fmt<W>(&this, f: mut &Formatter<W>) -> Result<(), FmtError>
where W: FmtWrite;
}Display / Debug / Formatter.
std::fmt::displaytype trait Debug {
fmt<W>(&this, f: mut &Formatter<W>) -> Result<(), FmtError>
where W: FmtWrite;
}type struct Array<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
length: i64;
capacity: i64;
alloc: A;
}Array<T, A>: growable, heap-backed, contiguous sequence.
std::collections::arrayfor (mut i: i32 = 0; i < n; i++) { ... }
for (item in iterable) { ... }Two forms. The C-style for (init; condition; step) scopes its loop variable to the body. for (x in expr) iterates anything with next() -> Option<T>: an iterator, a range such as 0..n, an Array or Slice (their iter() is inserted for you), or a fixed-size array.
xfor (item in iterable) { ... }Separates the loop variable from the sequence in a for loop. The sequence is evaluated once; the loop lowers to loop { match (it.next()) { Some(x) => .., None => break } }.
loop { ... }An unconditional loop; it runs until a break (or return) leaves it. Prefer it to while (true): it says outright that the exit is somewhere inside.
match (subject) {
Pattern(x) => { ... }
_ => { ... }
}The primary discriminator: branches on enum variants, integers, ranges, and destructuring patterns, and the compiler rejects a match that misses a case. There is no fallthrough. As an expression it evaluates to the chosen arm's value, so every arm must produce the same type.
Option::Nonebreak;Exits the innermost enclosing loop immediately - for, while, loop, or do. Inside for (x in ..) it leaves the loop the compiler synthesised around the iterator.
itype struct Slice<T> {
ptr: T*;
length: u64;
}Slice<T>: a borrowed view into a contiguous sequence.
std::core::slicepublic function name() { ... }
public:Visible to any module that imports this one - the default for top-level items and for struct fields, so it is mostly written to be explicit. public: opens a visibility block that groups the members after it.
private type struct Name { ... }
private:On a field: only the declaring type's own methods may touch it (E0353). On a top-level item: confined to its own module, and naming a private type elsewhere is E0503. private: opens a block of such members.
async function name(param: Type) -> T { ... }Compiles the function into a stackless state machine. Calling it builds a future whose output is the declared return type; nothing runs until that future is polled. Allowed on free functions, methods, and trait methods.
language referenceawait futureSuspends the enclosing async body until the operand - which must implement Future - completes, and evaluates to its output. A prefix operator allowed anywhere an expression is (conditions, arms, guards), but only inside async code.
function name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
async function maintype struct Executor {
inner: ExecInner*;
worker_tids: [u64];
}A multi-threaded, poll-driven task executor. Construct one, spawn futures onto it (keeping the JoinHandle to await a result, or dropping it to fire-and-forget), and block_on to drive a root future to its value. A pool of worker threads does all polling; the calling thread only ever blocks on a completion condvar.
type trait Allocator {
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
}Allocator: the trait every heap strategy implements.
std::alloc::allocatortype struct GlobalAlloc {}Zero-sized handle to the process-wide allocator. Construct with GlobalAlloc::new(); all instances dispatch through the same underlying backend.
type struct Arena {
head: Chunk*;
current: Chunk*;
chunk_size: u64;
}Arena: bump allocator with bulk release.
std::alloc::arenatype struct Pool {
slot: Layout;
slots_per_block: u64;
free_list: FreeNode*;
blocks: Block*;
}Pool: O(1) allocator for uniformly-sized slots.
std::alloc::pooltype struct Box<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
alloc: A;
}Box<T, A>: single-owner heap allocation.
std::alloc::boxtype struct Rc<T, A = GlobalAlloc> where A: Allocator {
inner: RcInner<T, A>*;
}Rc<T, A>: single-threaded reference counting, with weak references.
std::alloc::rctype struct Arc<T, A = GlobalAlloc> where A: Allocator {
inner: ArcInner<T, A>*;
}Arc<T, A>: atomic reference counting, with weak references.
std::alloc::arctype struct HashMap<K, V, A = GlobalAlloc> where A: Allocator {
buckets: Entry<K, V>**;
bucket_count: u64;
length: u64;
alloc: A;
seed: u64;
}HashMap<K, V, A>: key-value map with amortized O(1) operations.
std::collections::hashmaptype struct HashSet<T, A = GlobalAlloc> {
map: HashMap<T, (), A>;
}HashSet<T, A>: unordered collection of unique values.
std::collections::hashsettype struct Pair<A, B> {
first: A;
second: B;
}Pair<A, B>: an owned two-element tuple.
std::collections::pairtype struct Str {
bytes: u8*;
length: u64;
}Str: a borrowed UTF-8 string slice.
std::collections::strtype trait Eq {
equals(&this, other: &This) -> boolean;
}Types that support value equality. equals(a, b) must be reflexive, symmetric, and transitive.
type trait Ord : Eq {
compare(&this, other: &This) -> Ordering;
}Types that have a total order: every pair is Less, Equal, or Greater. compare must be consistent with equals: if a.equals(b) then a.compare(b) == Equal.
type trait Default {
static default() -> This;
}Default: a canonical "zero value" for a type.
std::core::defaulttype trait Into<T> {
into(&this) -> T;
}type trait TryFrom<T> {
static try_from(value: T) -> Result<This, ConversionError>;
}type trait TryInto<T> {
try_into(&this) -> Result<T, ConversionError>;
}type trait FmtWrite {
write_str(mut &this, source: Str) -> Result<(), FmtError>;
write_char(mut &this, c: char) -> Result<(), FmtError>;
}type struct TakeIter<I> {
inner: I;
remaining: u64;
}Adapter yielding at most remaining elements from inner.
type struct MapIter<I, O> where I: Iterator {
inner: I;
}Adapter applying f to each element of inner. The input element type is the inner iterator's associated item I::Item; O is the mapped result (Output) type, the only element-type struct parameter needed.
type struct FilterIter<I> where I: Iterator {
inner: I;
}Adapter yielding only the elements of inner for which pred holds.
type struct ChainIter<I, J> {
first: I;
second: J;
first_done: boolean;
}Adapter concatenating two iterators of the same element type: it drains first, then second. Both inner element types are pinned to the shared A by the where-bounds.
type struct EnumerateIter<I> {
inner: I;
index: u64;
}Adapter pairing each element of inner with its 0-based index. The element type is the inner iterator's associated item I::Item; the yielded item is Pair<u64, I::Item>.
type struct ZipIter<I, J> {
first: I;
second: J;
}Adapter pairing two iterators positionally, yielding Pair<A, O> until either side runs out. Chain-shaped: the element types A (from I) and O (from J) live only in the impl where-bounds, not as struct parameters, so the receiver type only mentions the two inner iterators.
mut c: Countermut z: ZipIter<.., ..>namespace std::collections::array;Array<T, A>: growable, heap-backed, contiguous sequence.
module pagefunction from_iter<I, T>(it: I) -> Array<T>
where I: Iterator<T>Collect every element an iterator yields into a fresh Array<T>, in order. it is consumed. T is recovered from the iterator's Iterator<T> impl, and the result element type is fixed by the expected type at the call site:
type trait Read {
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_byte(mut &this) -> Result<Option<u8>, IoError>;
read_char(mut &this) -> Result<Option<u32>, IoError>;
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;
}type trait Write {
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;
flush(mut &this) -> Result<(), IoError>;
write<T>(mut &this, data: T) -> Result<(), IoError>;
}type struct Stdin {}Handle to process standard input. Construction is free; all instances dispatch to file descriptor 0. Unbuffered: a line read that needs minimum syscalls should wrap this in a BufReader<Stdin> from io::buf.
type struct Stdout {}Handle to process standard output. Unbuffered; wrap in LineWriter<Stdout> or BufWriter<Stdout> from io::buf for the common "coalesce many small writes" case.
type struct Stderr {}Handle to process standard error. Unbuffered by convention so diagnostics appear immediately; do **not** wrap in BufWriter unless you also guarantee a flush on every path that might panic or exit.
type struct BufReader<R> where R: Read {
reader: R*;
buffer: u8*;
capacity: u64;
position: u64;
filled: u64;
}Pulls from R in buffer-sized chunks and serves reads from the buffer. Transforms a stream of small reads into a few large ones and makes read_line fast: no per-byte syscall.
type struct BufWriter<W> where W: Write {
writer: W*;
buffer: u8*;
capacity: u64;
length: u64;
}Coalesces writes destined for W into larger flushes. The inner writer is borrowed via pointer; the caller owns it and drops it.
type struct LineWriter<W> {
inner: BufWriter<W>;
}A BufWriter that flushes after any write containing a \n. Appropriate for interactive stdout on a TTY, where "the user saw the line as soon as it was emitted" matters more than coalescing.
type struct Path {
inner: Str;
}Path / PathBuf: filesystem paths as length-typed UTF-8.
std::fs::pathtype struct PathBuf<A = GlobalAlloc> {
inner: String<A>;
}type trait Future {
type Output;
poll(mut &this, cx: Context*) -> Poll<This::Output>;
}An asynchronous computation. poll drives it one step: Ready(v) when the value is available, Pending when it is not yet (the future has arranged, via cx's waker, to be polled again later).
type enum Poll<T> {
Ready(T);
Pending;
}The result of polling a Future: either the final value, or a signal that the value is not ready yet and the task should be re-polled after its Waker fires.
type struct Context {
waker: Waker;
}The context threaded through a poll call. Holds the Waker a future registers when it returns Pending. Passed by pointer down the poll tree, matching the stdlib convention of moving aggregates by pointer.
type struct Waker {
data: u8*;
}A handle a stalled future stores so it can be re-scheduled: wake_fn(data) tells the executor "poll my task again". This is the manual-vtable shape used throughout the runtime — non-capturing function pointers plus an opaque data pointer identifying the task.
type struct JoinHandle<O> {
shared: TaskShared<O>*;
exec: ExecInner*;
}JoinHandle is also declared in std::thread
A handle to a spawned task, yielding its Output via join(). Dropping a handle without join/detach detaches (the task runs on, its result discarded). abort() requests cancellation.
type struct Sleep {
deadline: i64;
id: u64;
rt: Reactor*;
}A future that completes once the monotonic clock reaches its deadline.
std::future::timertype struct TcpStream {
fd: i32;
}type struct TcpListener {
fd: i32;
}type struct UdpSocket {
fd: i32;
}type enum IpAddr {
V4(IpV4Addr);
V6(IpV6Addr);
}type struct IpV4Addr {
a: u8;
b: u8;
c: u8;
d: u8;
}type struct IpV6Addr {
segments: [u8;
16];
}Sixteen octets in network byte order. parse accepts the canonical text forms (full 8-group, ::-compressed, and trailing embedded-v4); addresses may also be constructed directly.
namespace std::net::http2;net::http2: HTTP/2 (RFC 7540) with HPACK header compression (RFC 7541).
module pagetype enum JsonValue {
Null;
Bool(boolean);
Number(JsonNumber);
String(String);
Array(Array<JsonValue>);
Object(JsonObject);
}One JSON value. Recursive through Array and Object.
type struct JsonObject {
keys: Array<String>;
values: Array<JsonValue>;
index: HashMap<String, u64>;
}JSON object. Insertion-ordered keys + parallel value array; a HashMap from String to slot index gives O(1) lookup. Owning; callers must drop before discarding.
type enum JsonNumber {
Int(i64);
UInt(u64);
Float(f64);
}JSON's single number type, split by source representation so integers round-trip exactly. Int covers signed values that fit i64; UInt carries values in (i64::MAX, u64::MAX]; everything else (decimals, exponents, NaN-shaped inputs the parser accepts as floats) is Float.
type struct Command {
program: String;
args: Array<String>;
envs: Array<EnvEntry>;
clear_env_flag: boolean;
cwd: Option<String>;
stdin_cfg: Stdio;
stdout_cfg: Stdio;
stderr_cfg: Stdio;
}Command: builder for spawning a subprocess.
std::process::commandtype struct Child {
stdin: Option<ChildStdin>;
stdout: Option<ChildStdout>;
stderr: Option<ChildStderr>;
}Child: a running subprocess.
std::process::childtype struct ExitStatus {
code: i32;
signal: i32;
signaled: boolean;
}Result of a child's termination. Either it exited normally with a code, or it was killed by a signal. POSIX encodes both into a single wstatus word; ExitStatus is the decoded form.
extern "C" function fork() -> i32extern "C" function execve(path: u8*, argv: u8**, envp: u8**) -> i32async Child::join(mut &this) -> Result<ExitStatus, IoError>Await the child's exit without blocking the calling thread: the async spelling of wait. Same stdin-close, same status, same waited bookkeeping — but the task parks and the executor worker stays free. ChildWait documents which of the two routes each platform takes.
async Command::collect(&this) -> Result<Output, IoError>Spawn, capture both streams, and await the exit without blocking the calling thread: the async spelling of output.
async Command::run(&this) -> Result<ExitStatus, IoError>Spawn and await the exit without capturing anything: the async spelling of status. Stdio goes wherever the caller configured it.
type struct PipeDrain {
fd: i32;
buf: Array<u8>;
rt: Reactor*;
job: PipeDrainJob*;
routed: boolean;
on_reactor: boolean;
}Read one captured pipe to EOF without stalling the executor. The machinery behind Command::collect; await that rather than driving this directly.
function args() -> Array<String>Program arguments as UTF-8 strings. The first element is the program name. Returns an empty array if the runtime hasn't published argv yet. Panics on allocation failure.
std::envtype struct Atomic<T> {
value: T;
}A single atomic cell of type T. See the module docs for the supported T and the compile-time dispatch model.
static match (T) { ... }Opens a compile-time match on a type parameter: the one arm whose type matches is kept during monomorphisation and the rest are discarded.
static match (T) {
u8 | u16 => { ... }
_ => { ... }
}Selects a body by inspecting a type parameter at compile time. The subject is a type and each arm is a type (| groups several; _ takes the rest). During monomorphisation the one matching arm is kept and the others discarded, so there is no runtime branch.
type enum MemoryOrder : u32 {
Relaxed = 2;
Acquire = 4;
Release = 5;
AcqRel = 6;
SeqCst = 7;
}Memory-ordering for an atomic operation.
std::sync::atomictype struct Mutex<T, A = GlobalAlloc> where A: Allocator {
inner: MutexInner<T, A>*;
}Mutex<T>: mutual-exclusion lock around a value.
std::sync::mutextype struct RwLock<T, A = GlobalAlloc> where A: Allocator {
inner: RwLockInner<T, A>*;
}RwLock<T>: read/write reader-writer lock around a value.
std::sync::rwlocktype struct CondVar {
inner: CondVarInner*;
}CondVar: condition variable for blocking until a predicate holds.
std::sync::condvartype struct Once {
inner: OnceInner*;
}Once: one-shot initialization synchronization.
std::sync::oncetype trait Send {}Types that are safe to transfer between threads. An owning value of a Send type may cross a thread boundary without violating memory safety.
type trait Sync {}Types that are safe to share between threads by shared reference. T: Sync if &T: Send.
type struct ThreadLocal<T> {
key: u32;
}type struct Scope {
tids: [u64];
stack_bytes: u64;
}A thread scope. Every thread spawned through it is guaranteed to be joined before the scope is torn down (explicitly via join_all() or automatically when the Scope drops), so scoped bodies may safely borrow data that outlives the scope - pass a pointer to it through the body's context:
type struct Sender<T> {
inner: ChannelInner<T>*;
}The sending half of a channel. Cloneable for multiple producers.
std::sync::mpsctype struct Receiver<T> {
inner: ChannelInner<T>*;
}The receiving half of a channel, and the channel's owner. Not cloneable (single consumer); mint producers with sender().
type struct Builder {
stack_bytes: u64;
name_buf: [u8;
16];
name_len: u64;
}A configurable thread spawn: set a stack size and/or an OS-visible thread name, then spawn (panics on failure) or try_spawn (returns a Result). Configuration is applied through a pthread_attr_t; the name is set with pthread_setname_np once the thread is running.
type struct Duration {
secs: u64;
nanos: u32;
}A length of time: whole secs plus a sub-second nanos remainder (0 <= nanos < 1_000_000_000). POD; copy-by-value, no drop.
type struct Instant {
secs: i64;
nanos: i64;
}A measurement of the monotonic clock. Opaque: the fields are the raw timespec, meaningful only relative to another Instant. POD.
type struct SystemTime {
secs: i64;
nanos: i64;
}A measurement of the wall clock (CLOCK_REALTIME) as a raw timespec. duration_since_epoch() yields a Unix timestamp. Subject to NTP steps and manual changes; do not use for elapsed-time measurement. POD.
function sleep(nanos: u64) -> voidSleep the current thread for at least nanos nanoseconds. On POSIX this restarts across signal interruptions (EINTR) so the full duration elapses; on Windows it rounds up to whole milliseconds.
type struct Rng {
s0: u64;
s1: u64;
s2: u64;
s3: u64;
}A fast non-cryptographic PRNG (xoshiro256**). The 256-bit state is the four words s0..s3.
type struct Formatter<W> {
writer: W*;
}function isatty(fd: i32) -> i32function spawn<C, T>(ctx: C, body: (C) -> T) -> JoinHandle<T>
where C: Send, T: SendSpawn a thread that runs body(ctx) and returns a handle to its T result. ctx is moved into the new thread. body must be a function pointer or non-capturing lambda. Panics on allocation or pthread_create failure; use try_spawn for a fallible spawn.