primitives
import std::core::primitives; — in the prelude · source
Types
Methods on primitive types
implement blocks can extend the built-in types, and core::primitives uses that sparingly — only where the operators do not already say it in one line. All of it is in the prelude.
Every numeric width carries static min_value() and static max_value(). The signed types carry abs; f32 and f64 carry abs and is_nan.
char
implement char {
is_digit(&this) -> boolean;
is_alpha(&this) -> boolean;
is_alphanumeric(&this) -> boolean;
is_hex_digit(&this) -> boolean;
is_whitespace(&this) -> boolean;
is_ascii(&this) -> boolean;
to_ascii_lowercase(&this) -> char;
to_ascii_uppercase(&this) -> char;
hex_value(&this) -> i32;
is_c_ident_start(&this) -> boolean;
is_c_ident_char(&this) -> boolean;
}
The ASCII classifiers, plus to_ascii_lowercase, to_ascii_uppercase, and hex_value (the digit's value, or -1 when it isn't one). Case folding is ASCII-only; full Unicode folding needs a table beyond this module.
Methods
is_digit(&this) -> boolean;
is_alpha(&this) -> boolean;
is_alphanumeric(&this) -> boolean;
is_hex_digit(&this) -> boolean;
is_hex_digit(&this) -> boolean;ASCII hexadecimal digit: 0-9, a-f, or A-F.
is_whitespace(&this) -> boolean;
is_ascii(&this) -> boolean;
is_ascii(&this) -> boolean;True when the scalar is in the 7-bit ASCII range (0..=127).
to_ascii_lowercase(&this) -> char;
to_ascii_lowercase(&this) -> char;ASCII fold to lowercase. Non-ASCII scalars pass through unchanged; full Unicode case folding requires a table beyond this module.
to_ascii_uppercase(&this) -> char;
to_ascii_uppercase(&this) -> char;ASCII fold to uppercase. Non-ASCII scalars pass through unchanged.
hex_value(&this) -> i32;
hex_value(&this) -> i32;Numeric value of a hex digit (0-9, a-f, A-F), or -1 when this is not a hex digit. Consolidates the nibble-decode loops that the compiler hand-rolls in literal/char parsing.
is_c_ident_start(&this) -> boolean;
is_c_ident_start(&this) -> boolean;True when this may begin a C identifier: an ASCII letter or _.
is_c_ident_char(&this) -> boolean;
is_c_ident_char(&this) -> boolean;True when this may continue a C identifier: letter, digit, or _.
Integers
Every signed width — i8, i16, i32, i64, i128, isize — has the same shape as i32:
implement i32 {
static min_value() -> i32;
static max_value() -> i32;
abs(&this) -> i32;
checked_abs(&this) -> Option<i32>;
clamp(&this, lo: i32, hi: i32) -> i32;
to_decimal_buf(&this, buffer: u8*) -> u64;
}
Every unsigned width — u8, u16, u32, u64, u128, usize — has the shape of u32:
implement u32 {
static min_value() -> u32;
static max_value() -> u32;
clamp(&this, lo: u32, hi: u32) -> u32;
to_decimal_buf(&this, buffer: u8*) -> u64;
to_hex_buf(&this, buffer: u8*) -> u64;
to_hex_upper_buf(&this, buffer: u8*) -> u64;
to_oct_buf(&this, buffer: u8*) -> u64;
to_bin_buf(&this, buffer: u8*) -> u64;
}
u64 additionally carries the padded and allocating forms:
implement u64 {
static min_value() -> u64;
static max_value() -> u64;
clamp(&this, lo: u64, hi: u64) -> u64;
to_decimal_buf(&this, buffer: u8*) -> u64;
to_decimal_str(&this) -> string;
to_hex_buf(&this, buffer: u8*) -> u64;
to_hex_upper_buf(&this, buffer: u8*) -> u64;
to_hex_padded_buf(&this, buffer: u8*, width: u64) -> u64;
to_hex_padded_str(&this, width: u64) -> string;
to_hex_padded_upper_buf(&this, buffer: u8*, width: u64) -> u64;
static to_hex_padded_buf_with_table(value: u64, buffer: u8*, width: u64, digits_table: u8*) -> u64;
to_oct_buf(&this, buffer: u8*) -> u64;
to_bin_buf(&this, buffer: u8*) -> u64;
to_decimal_padded_buf(&this, buffer: u8*, width: u64) -> u64;
}
Integer-to-text conversion lives here as buffer-writing methods rather than allocating ones: to_decimal_buf, and on the unsigned types also to_hex_buf, to_hex_upper_buf, to_oct_buf, and to_bin_buf. Each writes into a caller-owned u8* and returns the byte count. No heap traffic — the digit loop runs in a stack scratch and copies once. Size the buffer with the matching constant.
to_decimal_str on the 64-bit and wider types is the allocating form, returning a fresh C string the caller owns.
i32
Constructors
####### static min_value() -> i32;
####### static max_value() -> i32;
Methods
####### abs(&this) -> i32;
abs(&this) -> i32;Wraps at i32::min_value(): the most-negative value has no positive counterpart in two's complement, so i32::min_value().abs() is itself; checked_abs answers None there.
####### checked_abs(&this) -> Option<i32>;
checked_abs(&this) -> Option<i32>;Some(|this|), or None for min_value(), whose magnitude is not representable: only it negates to a value still negative.
####### clamp(&this, lo: i32, hi: i32) -> i32;
clamp(&this, lo: i32, hi: i32) -> i32;this confined to [lo, hi].
####### to_decimal_buf(&this, buffer: u8*) -> u64;
to_decimal_buf(&this, buffer: u8*) -> u64;Buffer must hold at least I32_MAX_DECIMAL_DIGITS bytes.
u32
Constructors
####### static min_value() -> u32;
####### static max_value() -> u32;
Methods
####### clamp(&this, lo: u32, hi: u32) -> u32;
clamp(&this, lo: u32, hi: u32) -> u32;this confined to [lo, hi].
####### to_decimal_buf(&this, buffer: u8*) -> u64;
####### to_hex_buf(&this, buffer: u8*) -> u64;
####### to_hex_upper_buf(&this, buffer: u8*) -> u64;
####### to_oct_buf(&this, buffer: u8*) -> u64;
####### to_bin_buf(&this, buffer: u8*) -> u64;
u64
Constructors
####### static min_value() -> u64;
####### static max_value() -> u64;
####### static to_hex_padded_buf_with_table(value: u64, buffer: u8*, width: u64, digits_table: u8*) -> u64;
Methods
####### clamp(&this, lo: u64, hi: u64) -> u64;
clamp(&this, lo: u64, hi: u64) -> u64;this confined to [lo, hi].
####### to_decimal_buf(&this, buffer: u8*) -> u64;
to_decimal_buf(&this, buffer: u8*) -> u64;Write this in base 10 into buffer. Returns bytes written. buffer must hold at least U64_MAX_DECIMAL_DIGITS bytes. Builds the digits on a 20-byte stack scratch then copies in one shot; no heap traffic.
####### to_decimal_str(&this) -> string;
to_decimal_str(&this) -> string;Decimal text on a fresh heap buffer (caller owns), mirroring C's "%llu". For a no-alloc path, write into your own buffer with to_decimal_buf.
####### to_hex_buf(&this, buffer: u8*) -> u64;
to_hex_buf(&this, buffer: u8*) -> u64;Lowercase hex. Returns bytes written. buffer must hold at least U64_MAX_HEX_DIGITS bytes.
####### to_hex_upper_buf(&this, buffer: u8*) -> u64;
to_hex_upper_buf(&this, buffer: u8*) -> u64;Uppercase variant.
####### to_hex_padded_buf(&this, buffer: u8*, width: u64) -> u64;
to_hex_padded_buf(&this, buffer: u8*, width: u64) -> u64;Zero-padded fixed-width hex. Writes exactly width characters, truncating high nibbles if the value doesn't fit. Useful for pointer formatting (width = 16), hash dumps, binary protocols.
####### to_hex_padded_str(&this, width: u64) -> string;
to_hex_padded_str(&this, width: u64) -> string;Zero-padded fixed-width lowercase hex on a fresh heap buffer (caller owns): exactly width characters plus a NUL. width = 16 renders a full u64 (the pointer/hash-dump convention).
####### to_hex_padded_upper_buf(&this, buffer: u8*, width: u64) -> u64;
####### to_oct_buf(&this, buffer: u8*) -> u64;
to_oct_buf(&this, buffer: u8*) -> u64;Base 8. buffer must hold at least U64_MAX_OCT_DIGITS bytes.
####### to_bin_buf(&this, buffer: u8*) -> u64;
to_bin_buf(&this, buffer: u8*) -> u64;Base 2. buffer must hold at least U64_MAX_BIN_DIGITS bytes.
####### to_decimal_padded_buf(&this, buffer: u8*, width: u64) -> u64;
to_decimal_padded_buf(&this, buffer: u8*, width: u64) -> u64;Zero-padded fixed-width decimal. Writes exactly width digits, truncating the high end if the value doesn't fit. Used for the fractional piece of a float where the digit count is known ahead of time.
Floats
implement f64 {
abs(&this) -> f64;
clamp(&this, lo: f64, hi: f64) -> f64;
is_nan(&this) -> boolean;
sqrt(&this) -> f64;
}
f32 has the same two methods. Float formatting is not here — it needs libm, and keeping libc out of core matters more. It lives in fmt::float.
Methods
abs(&this) -> f64;
abs(&this) -> f64;Absolute value by clearing the sign bit, so -0.0 gives 0.0 and a NaN keeps its payload with its sign cleared.
clamp(&this, lo: f64, hi: f64) -> f64;
clamp(&this, lo: f64, hi: f64) -> f64;this confined to [lo, hi], by plain comparisons: a NaN this compares false against both bounds and is returned unchanged.
is_nan(&this) -> boolean;
is_nan(&this) -> boolean;NaN != NaN, so the cheapest portable check is self-comparison.
sqrt(&this) -> f64;
sqrt(&this) -> f64;Square root: NaN for a negative this.
Bridge methods on string
implement string {
length(&this) -> u64;
is_empty(&this) -> boolean;
is_text_literal(&this) -> boolean;
is_float_literal(&this) -> boolean;
is_unsigned_literal(&this) -> boolean;
substring(&this, start: u32, len: u32) -> string;
substr(&this, start: i64, len: i64) -> string;
append(&this, other: string) -> string;
trim(&this) -> string;
strip_prefix(&this, prefix: string) -> string;
ends_with(&this, suffix: string) -> boolean;
common_prefix_len(&this, other: string) -> i64;
contains(&this, needle: string) -> boolean;
find_char(&this, ch: i8) -> i64;
rfind_char(&this, ch: i8) -> i64;
parse_int<T>(&this) -> T;
parse_c_uint(&this) -> u64;
strip_quotes(&this) -> string;
parent_dir(&this) -> string;
eq(&this, other: string) -> boolean;
starts_with(&this, prefix: string) -> boolean;
find(&this, needle: string) -> i64;
rfind(&this, needle: string) -> i64;
split_char(&this, sep: i8) -> [string];
split(&this, sep: string) -> [string];
split_nonempty(&this, sep: string) -> [string];
replace(&this, from: string, to: string) -> string;
to_ascii_lower(&this) -> string;
to_ascii_upper(&this) -> string;
basename(&this) -> string;
stem(&this) -> string;
extension(&this) -> string;
join(&this, seg: string) -> string;
is_under(&this, dir: string) -> boolean;
with_exe_suffix(&this, suffix: string) -> string;
}
The raw string type — a NUL-terminated C view — carries a set of convenience methods so the self-hosted compiler, which predates Str and String, keeps building without a rewrite. Every method that produces text allocates a fresh C string and leaks it to the caller. New code should prefer Str and String; these exist for the bridge.
Methods
length(&this) -> u64;
is_empty(&this) -> boolean;
is_text_literal(&this) -> boolean;
is_text_literal(&this) -> boolean;True when this token spelling is a C string or character literal ("...", 'c', or an encoding-prefixed form: L"...", u'...', U"...", u8"...", R"(...)"). Detected by the presence of a " or ' quote: a well-formed C numeric literal never contains one, so this correctly accepts the prefixed forms too - a prefix-scan that bailed on the first digit would misread the 8 in u8"..." as a numeric literal.
is_float_literal(&this) -> boolean;
is_float_literal(&this) -> boolean;True when this numeric-literal token spelling is a C floating-point constant. A decimal float carries a . or a decimal exponent (e/E); a hexadecimal float (0x...) carries a . or a binary exponent (p/P). The hex case is handled distinctly because in hex the letters e/E are digits, not an exponent - and p/P is the definitive float marker, so a dot-less hex float such as 0x1p4 is correctly recognized (a ./e only scan would miss it and mis-bind it as an integer). Assumes a numeric literal - rule out string/char literals with is_text_literal first.
is_unsigned_literal(&this) -> boolean;
is_unsigned_literal(&this) -> boolean;True when this integer-literal token spelling carries an unsigned type suffix (u/U). Only the trailing suffix run is inspected, stepping over any l/L length suffix, so 5u, 0xFFul, 10LU, and 7llu all report unsigned while 5, 5l, and 7ll do not.
substring(&this, start: u32, len: u32) -> string;
substring(&this, start: u32, len: u32) -> string;substring(start, len): extract len bytes starting at start, returning a freshly allocated NUL-terminated string. Matches the legacy compiler's call convention (start, length), not (start, end).
substr(&this, start: i64, len: i64) -> string;
substr(&this, start: i64, len: i64) -> string;Signed-offset slice: like substring but robust to the computed ranges cstring-style code produces. A non-positive len (or an out-of-range start) yields ""; an over-long len is clamped to the remaining bytes, so callers never need to bounds-check first. It reads no further than start + len: a tokenizer slicing a token off the rest of a file pays for the token, not for the rest of the file.
append(&this, other: string) -> string;
append(&this, other: string) -> string;Concatenate other onto a fresh heap-allocated copy of this, returning the new NUL-terminated string. Caller owns the result.
trim(&this) -> string;
trim(&this) -> string;Trim leading and trailing ASCII whitespace (space, tab, LF, CR), returning a freshly allocated string ("" when all whitespace).
strip_prefix(&this, prefix: string) -> string;
strip_prefix(&this, prefix: string) -> string;If this begins with prefix, return the remainder as a fresh string; otherwise return this unchanged (same buffer).
ends_with(&this, suffix: string) -> boolean;
ends_with(&this, suffix: string) -> boolean;True when this ends with suffix (byte-wise). An empty suffix always matches; a suffix longer than this never does.
common_prefix_len(&this, other: string) -> i64;
common_prefix_len(&this, other: string) -> i64;Length, in bytes, of the longest common leading prefix of this and other. Useful for ranking candidates by shared-path overlap.
contains(&this, needle: string) -> boolean;
contains(&this, needle: string) -> boolean;True when needle occurs anywhere in this (substring search). An empty needle always matches, mirroring C strstr.
find_char(&this, ch: i8) -> i64;
find_char(&this, ch: i8) -> i64;Byte index of the first occurrence of ch, or -1 if absent.
rfind_char(&this, ch: i8) -> i64;
rfind_char(&this, ch: i8) -> i64;Byte index of the last occurrence of ch, or -1 if absent.
parse_int<T>(&this) -> T;
parse_int<T>(&this) -> T;Parse this into an integer of the caller-chosen type T. Recognises an optional leading sign (signed T only), a 0x/0o/0b radix prefix, and _ digit separators; parsing stops at the first character invalid for the detected base. T is dispatched at compile time via static match, so each instantiation is exactly the right-width parser: lexeme.parse_int<u64>(), version.parse_int<i64>().
parse_c_uint(&this) -> u64;
parse_c_uint(&this) -> u64;Parse this as a C integer literal with strtoull(s, null, 0) semantics: an optional sign, then 0x/0X hex, 0b/0B binary, 0o/0O or a bare leading 0 octal, else decimal; _ separators are skipped and parsing stops at the first character invalid for the detected base (e.g. a U/L type suffix). Unlike parse_int, a bare leading 0 selects octal - matching C header #defines like 0755. INFALLIBLE: malformed input yields 0 and overflow wraps.
strip_quotes(&this) -> string;
strip_quotes(&this) -> string;Strip one pair of surrounding ASCII double quotes if both are present; otherwise return this unchanged (same buffer).
parent_dir(&this) -> string;
parent_dir(&this) -> string;The directory portion of a path: everything before the last / or \ separator, or "." when there is no leading directory component.
eq(&this, other: string) -> boolean;
eq(&this, other: string) -> boolean;Byte-wise content equality, taking other BY VALUE so it accepts string literals directly (name.eq("void")). This is the ergonomic replacement for the strcmp(a, b) == 0 idiom; the Eq trait's equals(&string) needs an lvalue and can't take a literal. Two nulls are equal; exactly one null is not.
starts_with(&this, prefix: string) -> boolean;
starts_with(&this, prefix: string) -> boolean;True when this begins with prefix (byte-wise). An empty prefix always matches; a prefix longer than this never does.
find(&this, needle: string) -> i64;
find(&this, needle: string) -> i64;Byte index of the first occurrence of needle, or -1 when absent. An empty needle matches at 0.
rfind(&this, needle: string) -> i64;
rfind(&this, needle: string) -> i64;Byte index of the last occurrence of needle, or -1 when absent. An empty needle matches at the end (the string's length).
split_char(&this, sep: i8) -> [string];
split_char(&this, sep: i8) -> [string];Split on a single byte separator, returning each piece as a freshly allocated string. Adjacent separators yield empty pieces; the result always has (separator-count + 1) entries.
split(&this, sep: string) -> [string];
split(&this, sep: string) -> [string];Split on a multi-byte separator string. An empty separator yields the whole string as a single piece. Covers ::-style segmentation.
split_nonempty(&this, sep: string) -> [string];
split_nonempty(&this, sep: string) -> [string];Like split, but drops empty pieces: leading, trailing, and consecutive separators produce no entry, and empty input yields an empty array. Useful for ::-delimited names and /-delimited paths where blank segments are meaningless.
replace(&this, from: string, to: string) -> string;
replace(&this, from: string, to: string) -> string;Replace every non-overlapping occurrence of from with to, returning a freshly allocated string. An empty from returns this unchanged.
to_ascii_lower(&this) -> string;
to_ascii_lower(&this) -> string;ASCII-fold to lowercase, returning a freshly allocated string.
to_ascii_upper(&this) -> string;
to_ascii_upper(&this) -> string;ASCII-fold to uppercase, returning a freshly allocated string.
basename(&this) -> string;
basename(&this) -> string;The final path component: everything after the last / or \.
stem(&this) -> string;
stem(&this) -> string;The file stem: basename with its final .ext removed. A leading-dot name (e.g. .gitignore) is treated as having no extension.
extension(&this) -> string;
extension(&this) -> string;The file extension without the dot, or "" when there is none. A leading-dot name (e.g. .gitignore) has no extension.
join(&this, seg: string) -> string;
join(&this, seg: string) -> string;Join seg onto this with a single / separator. An empty this returns seg; an empty seg returns this; an absolute seg (leading separator) replaces this entirely.
is_under(&this, dir: string) -> boolean;
is_under(&this, dir: string) -> boolean;True when this lies within directory dir: equal to dir, or extending it across a path separator. Boundary-aware so /a/bc is NOT under /a/b.
with_exe_suffix(&this, suffix: string) -> string;
with_exe_suffix(&this, suffix: string) -> string;Append suffix unless it is empty or already present at the end. Used to add a platform executable suffix (e.g. .exe) idempotently.
Integer overflow is wrapping
Integer arithmetic at every width is silent two's-complement wrapping on overflow. There is no trap and no diagnostic. This is a deliberate, frozen part of the 1.0 surface: Cryo ships no checked_*, wrapping_*, or saturating_* family, so code that must detect overflow has to range-check its operands first.
One visible consequence is abs: the most-negative value of a signed type has no positive counterpart, so i32::min_value().abs() is itself.
Constants
const U8_MAX_DECIMAL_DIGITS: u64 = 3;
const U16_MAX_DECIMAL_DIGITS: u64 = 5;
const U32_MAX_DECIMAL_DIGITS: u64 = 10;
const U64_MAX_DECIMAL_DIGITS: u64 = 20;
const U128_MAX_DECIMAL_DIGITS: u64 = 39;
const I8_MAX_DECIMAL_DIGITS: u64 = 4;
const I16_MAX_DECIMAL_DIGITS: u64 = 6;
const I32_MAX_DECIMAL_DIGITS: u64 = 11;
const I64_MAX_DECIMAL_DIGITS: u64 = 20;
const I128_MAX_DECIMAL_DIGITS: u64 = 40;
const U8_MAX_HEX_DIGITS: u64 = 2;
const U16_MAX_HEX_DIGITS: u64 = 4;
const U32_MAX_HEX_DIGITS: u64 = 8;
const U64_MAX_HEX_DIGITS: u64 = 16;
const U128_MAX_HEX_DIGITS: u64 = 32;
const U8_MAX_OCT_DIGITS: u64 = 3;
const U16_MAX_OCT_DIGITS: u64 = 6;
const U32_MAX_OCT_DIGITS: u64 = 11;
const U64_MAX_OCT_DIGITS: u64 = 22;
const U128_MAX_OCT_DIGITS: u64 = 43;
const U8_MAX_BIN_DIGITS: u64 = 8;
const U16_MAX_BIN_DIGITS: u64 = 16;
const U32_MAX_BIN_DIGITS: u64 = 32;
const U64_MAX_BIN_DIGITS: u64 = 64;
const U128_MAX_BIN_DIGITS: u64 = 128;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.
char::is_digit(&this) -> boolean&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
char::is_alpha(&this) -> booleanchar::is_alphanumeric(&this) -> booleanchar::is_hex_digit(&this) -> booleanASCII hexadecimal digit: 0-9, a-f, or A-F.
char::is_whitespace(&this) -> booleanchar::is_ascii(&this) -> booleanTrue when the scalar is in the 7-bit ASCII range (0..=127).
char::to_ascii_lowercase(&this) -> charASCII fold to lowercase. Non-ASCII scalars pass through unchanged; full Unicode case folding requires a table beyond this module.
char::to_ascii_uppercase(&this) -> charASCII fold to uppercase. Non-ASCII scalars pass through unchanged.
char::hex_value(&this) -> i32Numeric value of a hex digit (0-9, a-f, A-F), or -1 when this is not a hex digit. Consolidates the nibble-decode loops that the compiler hand-rolls in literal/char parsing.
char::is_c_ident_start(&this) -> booleanTrue when this may begin a C identifier: an ASCII letter or _.
char::is_c_ident_char(&this) -> booleanTrue when this may continue a C identifier: letter, digit, or _.
static name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static i32::min_value() -> i32static i32::max_value() -> i32i32::abs(&this) -> i32Wraps at i32::min_value(): the most-negative value has no positive counterpart in two's complement, so i32::min_value().abs() is itself; checked_abs answers None there.
i32::checked_abs(&this) -> Option<i32>Some(|this|), or None for min_value(), whose magnitude is not representable: only it negates to a value still negative.
i32::clamp(&this, lo: i32, hi: i32) -> i32this confined to [lo, hi].
(parameter) lo: i32(parameter) hi: i32i32::to_decimal_buf(&this, buffer: u8*) -> u64Buffer must hold at least I32_MAX_DECIMAL_DIGITS bytes.
(parameter) buffer: u8*static u32::min_value() -> u32static u32::max_value() -> u32u32::clamp(&this, lo: u32, hi: u32) -> u32this confined to [lo, hi].
(parameter) lo: u32(parameter) hi: u32u32::to_decimal_buf(&this, buffer: u8*) -> u64u32::to_hex_buf(&this, buffer: u8*) -> u64u32::to_hex_upper_buf(&this, buffer: u8*) -> u64u32::to_oct_buf(&this, buffer: u8*) -> u64u32::to_bin_buf(&this, buffer: u8*) -> u64static u64::min_value() -> u64static u64::max_value() -> u64u64::clamp(&this, lo: u64, hi: u64) -> u64this confined to [lo, hi].
(parameter) lo: u64(parameter) hi: u64u64::to_decimal_buf(&this, buffer: u8*) -> u64Write this in base 10 into buffer. Returns bytes written. buffer must hold at least U64_MAX_DECIMAL_DIGITS bytes. Builds the digits on a 20-byte stack scratch then copies in one shot; no heap traffic.
u64::to_decimal_str(&this) -> stringDecimal text on a fresh heap buffer (caller owns), mirroring C's "%llu". For a no-alloc path, write into your own buffer with to_decimal_buf.
primitive stringNUL-terminated raw string (u8*), matching the C ABI. Length-typed text is Str / String.
u64::to_hex_buf(&this, buffer: u8*) -> u64Lowercase hex. Returns bytes written. buffer must hold at least U64_MAX_HEX_DIGITS bytes.
u64::to_hex_upper_buf(&this, buffer: u8*) -> u64Uppercase variant.
u64::to_hex_padded_buf(&this, buffer: u8*, width: u64) -> u64Zero-padded fixed-width hex. Writes exactly width characters, truncating high nibbles if the value doesn't fit. Useful for pointer formatting (width = 16), hash dumps, binary protocols.
(parameter) width: u64u64::to_hex_padded_str(&this, width: u64) -> stringZero-padded fixed-width lowercase hex on a fresh heap buffer (caller owns): exactly width characters plus a NUL. width = 16 renders a full u64 (the pointer/hash-dump convention).
u64::to_hex_padded_upper_buf(&this, buffer: u8*, width: u64) -> u64static u64::to_hex_padded_buf_with_table(value: u64, buffer: u8*, width: u64, digits_table: u8*) -> u64(parameter) value: u64(parameter) digits_table: u8*u64::to_oct_buf(&this, buffer: u8*) -> u64Base 8. buffer must hold at least U64_MAX_OCT_DIGITS bytes.
u64::to_bin_buf(&this, buffer: u8*) -> u64Base 2. buffer must hold at least U64_MAX_BIN_DIGITS bytes.
u64::to_decimal_padded_buf(&this, buffer: u8*, width: u64) -> u64Zero-padded fixed-width decimal. Writes exactly width digits, truncating the high end if the value doesn't fit. Used for the fractional piece of a float where the digit count is known ahead of time.
f64::abs(&this) -> f64Absolute value by clearing the sign bit, so -0.0 gives 0.0 and a NaN keeps its payload with its sign cleared.
f64::clamp(&this, lo: f64, hi: f64) -> f64this confined to [lo, hi], by plain comparisons: a NaN this compares false against both bounds and is returned unchanged.
(parameter) lo: f64(parameter) hi: f64f64::is_nan(&this) -> booleanNaN != NaN, so the cheapest portable check is self-comparison.
f64::sqrt(&this) -> f64Square root: NaN for a negative this.
string::length(&this) -> u64string::is_empty(&this) -> booleanstring::is_text_literal(&this) -> booleanTrue when this token spelling is a C string or character literal ("...", 'c', or an encoding-prefixed form: L"...", u'...', U"...", u8"...", R"(...)").
string::is_float_literal(&this) -> booleanTrue when this numeric-literal token spelling is a C floating-point constant. A decimal float carries a . or a decimal exponent (e/E); a hexadecimal float (0x...) carries a . or a binary exponent (p/P).
string::is_unsigned_literal(&this) -> booleanTrue when this integer-literal token spelling carries an unsigned type suffix (u/U). Only the trailing suffix run is inspected, stepping over any l/L length suffix, so 5u, 0xFFul, 10LU, and 7llu all report unsigned while 5, 5l, and 7ll do not.
string::substring(&this, start: u32, len: u32) -> stringsubstring(start, len): extract len bytes starting at start, returning a freshly allocated NUL-terminated string. Matches the legacy compiler's call convention (start, length), not (start, end).
(parameter) start: u32(parameter) len: u32string::substr(&this, start: i64, len: i64) -> stringSigned-offset slice: like substring but robust to the computed ranges cstring-style code produces. A non-positive len (or an out-of-range start) yields ""; an over-long len is clamped to the remaining bytes, so callers never need to bounds-check first.
(parameter) start: i64(parameter) len: i64string::append(&this, other: string) -> stringConcatenate other onto a fresh heap-allocated copy of this, returning the new NUL-terminated string. Caller owns the result.
(parameter) other: stringstring::trim(&this) -> stringTrim leading and trailing ASCII whitespace (space, tab, LF, CR), returning a freshly allocated string ("" when all whitespace).
string::strip_prefix(&this, prefix: string) -> stringIf this begins with prefix, return the remainder as a fresh string; otherwise return this unchanged (same buffer).
(parameter) prefix: stringstring::ends_with(&this, suffix: string) -> booleanTrue when this ends with suffix (byte-wise). An empty suffix always matches; a suffix longer than this never does.
(parameter) suffix: stringstring::common_prefix_len(&this, other: string) -> i64Length, in bytes, of the longest common leading prefix of this and other. Useful for ranking candidates by shared-path overlap.
string::contains(&this, needle: string) -> booleanTrue when needle occurs anywhere in this (substring search). An empty needle always matches, mirroring C strstr.
(parameter) needle: stringstring::find_char(&this, ch: i8) -> i64Byte index of the first occurrence of ch, or -1 if absent.
(parameter) ch: i8string::rfind_char(&this, ch: i8) -> i64Byte index of the last occurrence of ch, or -1 if absent.
string::parse_int<T>(&this) -> TParse this into an integer of the caller-chosen type T. Recognises an optional leading sign (signed T only), a 0x/0o/0b radix prefix, and _ digit separators; parsing stops at the first character invalid for the detected base.
type parameter Ttype parameter Tstring::parse_c_uint(&this) -> u64Parse this as a C integer literal with strtoull(s, null, 0) semantics: an optional sign, then 0x/0X hex, 0b/0B binary, 0o/0O or a bare leading 0 octal, else decimal; _ separators are skipped and parsing stops at the first character invalid for the detected base (e.g. a U/L type suffix).
string::strip_quotes(&this) -> stringStrip one pair of surrounding ASCII double quotes if both are present; otherwise return this unchanged (same buffer).
string::parent_dir(&this) -> stringThe directory portion of a path: everything before the last / or \ separator, or "." when there is no leading directory component.
string::eq(&this, other: string) -> booleanByte-wise content equality, taking other BY VALUE so it accepts string literals directly (name.eq("void")). This is the ergonomic replacement for the strcmp(a, b) == 0 idiom; the Eq trait's equals(&string) needs an lvalue and can't take a literal. Two nulls are equal; exactly one null is not.
string::starts_with(&this, prefix: string) -> booleanTrue when this begins with prefix (byte-wise). An empty prefix always matches; a prefix longer than this never does.
string::find(&this, needle: string) -> i64Byte index of the first occurrence of needle, or -1 when absent. An empty needle matches at 0.
string::rfind(&this, needle: string) -> i64Byte index of the last occurrence of needle, or -1 when absent. An empty needle matches at the end (the string's length).
string::split_char(&this, sep: i8) -> [string]Split on a single byte separator, returning each piece as a freshly allocated string. Adjacent separators yield empty pieces; the result always has (separator-count + 1) entries.
(parameter) sep: i8string::split(&this, sep: string) -> [string]Split on a multi-byte separator string. An empty separator yields the whole string as a single piece. Covers ::-style segmentation.
(parameter) sep: stringstring::split_nonempty(&this, sep: string) -> [string]Like split, but drops empty pieces: leading, trailing, and consecutive separators produce no entry, and empty input yields an empty array. Useful for ::-delimited names and /-delimited paths where blank segments are meaningless.
string::replace(&this, from: string, to: string) -> stringReplace every non-overlapping occurrence of from with to, returning a freshly allocated string. An empty from returns this unchanged.
(parameter) from: string(parameter) to: stringstring::to_ascii_lower(&this) -> stringASCII-fold to lowercase, returning a freshly allocated string.
string::to_ascii_upper(&this) -> stringASCII-fold to uppercase, returning a freshly allocated string.
string::basename(&this) -> stringThe final path component: everything after the last / or \.
string::stem(&this) -> stringThe file stem: basename with its final .ext removed. A leading-dot name (e.g. .gitignore) is treated as having no extension.
string::extension(&this) -> stringThe file extension without the dot, or "" when there is none. A leading-dot name (e.g. .gitignore) has no extension.
string::join(&this, seg: string) -> stringJoin seg onto this with a single / separator. An empty this returns seg; an empty seg returns this; an absolute seg (leading separator) replaces this entirely.
(parameter) seg: stringstring::is_under(&this, dir: string) -> booleanTrue when this lies within directory dir: equal to dir, or extending it across a path separator. Boundary-aware so /a/bc is NOT under /a/b.
(parameter) dir: stringstring::with_exe_suffix(&this, suffix: string) -> stringAppend suffix unless it is empty or already present at the end. Used to add a platform executable suffix (e.g. .exe) idempotently.
const NAME: Type = value;At module level, a true compile-time constant, conventionally SCREAMING_SNAKE_CASE. (mut at module level declares mutable global state instead.)
const U8_MAX_DECIMAL_DIGITS: u64 = 3;const U16_MAX_DECIMAL_DIGITS: u64 = 5;const U32_MAX_DECIMAL_DIGITS: u64 = 10;const U64_MAX_DECIMAL_DIGITS: u64 = 20;const U128_MAX_DECIMAL_DIGITS: u64 = 39;const I8_MAX_DECIMAL_DIGITS: u64 = 4;const I16_MAX_DECIMAL_DIGITS: u64 = 6;const I32_MAX_DECIMAL_DIGITS: u64 = 11;const I64_MAX_DECIMAL_DIGITS: u64 = 20;const I128_MAX_DECIMAL_DIGITS: u64 = 40;const U8_MAX_HEX_DIGITS: u64 = 2;const U16_MAX_HEX_DIGITS: u64 = 4;const U32_MAX_HEX_DIGITS: u64 = 8;const U64_MAX_HEX_DIGITS: u64 = 16;const U128_MAX_HEX_DIGITS: u64 = 32;const U8_MAX_OCT_DIGITS: u64 = 3;const U16_MAX_OCT_DIGITS: u64 = 6;const U32_MAX_OCT_DIGITS: u64 = 11;const U64_MAX_OCT_DIGITS: u64 = 22;const U128_MAX_OCT_DIGITS: u64 = 43;const U8_MAX_BIN_DIGITS: u64 = 8;const U16_MAX_BIN_DIGITS: u64 = 16;const U32_MAX_BIN_DIGITS: u64 = 32;const U64_MAX_BIN_DIGITS: u64 = 64;const U128_MAX_BIN_DIGITS: u64 = 128;import a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
static i8::min_value() -> i8static i8::max_value() -> i8i8::abs(&this) -> i8f32::is_nan(&this) -> booleanchar::to_ascii_lowercase(&this) -> charASCII fold to lowercase. Non-ASCII scalars pass through unchanged; full Unicode case folding requires a table beyond this module.
std::core::primitiveschar::to_ascii_uppercase(&this) -> charASCII fold to uppercase. Non-ASCII scalars pass through unchanged.
std::core::primitiveschar::hex_value(&this) -> i32Numeric value of a hex digit (0-9, a-f, A-F), or -1 when this is not a hex digit. Consolidates the nibble-decode loops that the compiler hand-rolls in literal/char parsing.
char::is_digit(&this) -> booleanchar::is_alpha(&this) -> booleanchar::is_alphanumeric(&this) -> booleanchar::is_whitespace(&this) -> booleanchar::is_ascii(&this) -> booleanTrue when the scalar is in the 7-bit ASCII range (0..=127).
std::core::primitiveschar::is_c_ident_start(&this) -> booleanTrue when this may begin a C identifier: an ASCII letter or _.
char::is_c_ident_char(&this) -> booleanTrue when this may continue a C identifier: letter, digit, or _.
primitive usizePointer-width unsigned integer; the natural type for sizes and indices.
primitive typei8::to_decimal_buf(&this, buffer: u8*) -> u64Buffer must hold at least I8_MAX_DECIMAL_DIGITS bytes.
u8::to_hex_buf(&this, buffer: u8*) -> u64u8::to_hex_upper_buf(&this, buffer: u8*) -> u64u8::to_oct_buf(&this, buffer: u8*) -> u64u8::to_bin_buf(&this, buffer: u8*) -> u64i64::to_decimal_str(&this) -> stringDecimal text on a fresh heap buffer (caller owns), mirroring C's "%lld". For a no-alloc path, write into your own buffer with to_decimal_buf.
static i32::min_value() -> i32i32::abs(&this) -> i32Wraps at i32::min_value(): the most-negative value has no positive counterpart in two's complement, so i32::min_value().abs() is itself; checked_abs answers None there.
i8::checked_abs(&this) -> Option<i8>Some(|this|), or None for min_value(), whose magnitude is not representable: only it negates to a value still negative.
Option::NoneOption::Some(T)const I32_MAX_DECIMAL_DIGITS: u64 = 11;static u64::to_hex_padded_buf_with_table(value: u64, buffer: u8*, width: u64, digits_table: u8*) -> u64const U64_MAX_DECIMAL_DIGITS: u64 = 20;const U64_MAX_HEX_DIGITS: u64 = 16;u64::to_hex_padded_buf(&this, buffer: u8*, width: u64) -> u64Zero-padded fixed-width hex. Writes exactly width characters, truncating high nibbles if the value doesn't fit. Useful for pointer formatting (width = 16), hash dumps, binary protocols.
u64::to_hex_padded_str(&this, width: u64) -> stringZero-padded fixed-width lowercase hex on a fresh heap buffer (caller owns): exactly width characters plus a NUL. width = 16 renders a full u64 (the pointer/hash-dump convention).
u64::to_hex_padded_upper_buf(&this, buffer: u8*, width: u64) -> u64const U64_MAX_OCT_DIGITS: u64 = 22;const U64_MAX_BIN_DIGITS: u64 = 64;u64::to_decimal_padded_buf(&this, buffer: u8*, width: u64) -> u64Zero-padded fixed-width decimal. Writes exactly width digits, truncating the high end if the value doesn't fit. Used for the fractional piece of a float where the digit count is known ahead of time.
f32::sqrt(&this) -> f32Square root, in single precision: NaN for a negative this.
type struct Str {
bytes: u8*;
length: u64;
}Str: a borrowed UTF-8 string slice.
std::collections::strtype struct String<A = GlobalAlloc> {
buffer: RawBuffer<u8, A>;
length: u64;
}String: owned, heap-allocated, length-typed UTF-8.
std::collections::stringstring::length(&this) -> u64string::is_empty(&this) -> booleanstring::is_text_literal(&this) -> booleanTrue when this token spelling is a C string or character literal ("...", 'c', or an encoding-prefixed form: L"...", u'...', U"...", u8"...", R"(...)").
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.
string::is_float_literal(&this) -> booleanTrue when this numeric-literal token spelling is a C floating-point constant. A decimal float carries a . or a decimal exponent (e/E); a hexadecimal float (0x...) carries a . or a binary exponent (p/P).
string::is_unsigned_literal(&this) -> booleanTrue when this integer-literal token spelling carries an unsigned type suffix (u/U). Only the trailing suffix run is inspected, stepping over any l/L length suffix, so 5u, 0xFFul, 10LU, and 7llu all report unsigned while 5, 5l, and 7ll do not.
string::substring(&this, start: u32, len: u32) -> stringsubstring(start, len): extract len bytes starting at start, returning a freshly allocated NUL-terminated string. Matches the legacy compiler's call convention (start, length), not (start, end).
string::substr(&this, start: i64, len: i64) -> stringSigned-offset slice: like substring but robust to the computed ranges cstring-style code produces. A non-positive len (or an out-of-range start) yields ""; an over-long len is clamped to the remaining bytes, so callers never need to bounds-check first.
string::append(&this, other: string) -> stringConcatenate other onto a fresh heap-allocated copy of this, returning the new NUL-terminated string. Caller owns the result.
string::trim(&this) -> stringTrim leading and trailing ASCII whitespace (space, tab, LF, CR), returning a freshly allocated string ("" when all whitespace).
std::core::primitivesstring::strip_prefix(&this, prefix: string) -> stringIf this begins with prefix, return the remainder as a fresh string; otherwise return this unchanged (same buffer).
string::ends_with(&this, suffix: string) -> booleanTrue when this ends with suffix (byte-wise). An empty suffix always matches; a suffix longer than this never does.
string::common_prefix_len(&this, other: string) -> i64Length, in bytes, of the longest common leading prefix of this and other. Useful for ranking candidates by shared-path overlap.
string::contains(&this, needle: string) -> booleanTrue when needle occurs anywhere in this (substring search). An empty needle always matches, mirroring C strstr.
string::find_char(&this, ch: i8) -> i64Byte index of the first occurrence of ch, or -1 if absent.
string::rfind_char(&this, ch: i8) -> i64Byte index of the last occurrence of ch, or -1 if absent.
string::parse_int<T>(&this) -> TParse this into an integer of the caller-chosen type T. Recognises an optional leading sign (signed T only), a 0x/0o/0b radix prefix, and _ digit separators; parsing stops at the first character invalid for the detected base.
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.
string::parse_c_uint(&this) -> u64Parse this as a C integer literal with strtoull(s, null, 0) semantics: an optional sign, then 0x/0X hex, 0b/0B binary, 0o/0O or a bare leading 0 octal, else decimal; _ separators are skipped and parsing stops at the first character invalid for the detected base (e.g. a U/L type suffix).
extern "C" function strtoull(s: u8*, endptr: u8**, base: i32) -> u64nullThe null pointer literal, valid in any pointer context - including the primitive string, which is a NUL-terminated u8*. Compare with == null; it is not an Option.
string::strip_quotes(&this) -> stringStrip one pair of surrounding ASCII double quotes if both are present; otherwise return this unchanged (same buffer).
string::parent_dir(&this) -> stringThe directory portion of a path: everything before the last / or \ separator, or "." when there is no leading directory component.
string::eq(&this, other: string) -> booleanByte-wise content equality, taking other BY VALUE so it accepts string literals directly (name.eq("void")). This is the ergonomic replacement for the strcmp(a, b) == 0 idiom; the Eq trait's equals(&string) needs an lvalue and can't take a literal. Two nulls are equal; exactly one null is not.
extern "C" function strcmp(s1: u8*, s2: u8*) -> i32type trait Eq {
equals(&this, other: &This) -> boolean;
}Types that support value equality. equals(a, b) must be reflexive, symmetric, and transitive.
string::starts_with(&this, prefix: string) -> booleanTrue when this begins with prefix (byte-wise). An empty prefix always matches; a prefix longer than this never does.
string::find(&this, needle: string) -> i64Byte index of the first occurrence of needle, or -1 when absent. An empty needle matches at 0.
string::rfind(&this, needle: string) -> i64Byte index of the last occurrence of needle, or -1 when absent. An empty needle matches at the end (the string's length).
string::split_char(&this, sep: i8) -> [string]Split on a single byte separator, returning each piece as a freshly allocated string. Adjacent separators yield empty pieces; the result always has (separator-count + 1) entries.
std::core::primitivesstring::split(&this, sep: string) -> [string]Split on a multi-byte separator string. An empty separator yields the whole string as a single piece. Covers ::-style segmentation.
string::split_nonempty(&this, sep: string) -> [string]Like split, but drops empty pieces: leading, trailing, and consecutive separators produce no entry, and empty input yields an empty array. Useful for ::-delimited names and /-delimited paths where blank segments are meaningless.
string::replace(&this, from: string, to: string) -> stringReplace every non-overlapping occurrence of from with to, returning a freshly allocated string. An empty from returns this unchanged.
// reservedA reserved keyword with no syntax of its own in the current grammar. The standard library uses it freely as a method and parameter name (Str::from, from: u64).
string::to_ascii_lower(&this) -> stringASCII-fold to lowercase, returning a freshly allocated string.
std::core::primitivesstring::to_ascii_upper(&this) -> stringASCII-fold to uppercase, returning a freshly allocated string.
std::core::primitivesstring::basename(&this) -> stringThe final path component: everything after the last / or \.
string::stem(&this) -> stringThe file stem: basename with its final .ext removed. A leading-dot name (e.g. .gitignore) is treated as having no extension.
string::extension(&this) -> stringThe file extension without the dot, or "" when there is none. A leading-dot name (e.g. .gitignore) has no extension.
string::join(&this, seg: string) -> stringJoin seg onto this with a single / separator. An empty this returns seg; an empty seg returns this; an absolute seg (leading separator) replaces this entirely.
string::is_under(&this, dir: string) -> booleanTrue when this lies within directory dir: equal to dir, or extending it across a path separator. Boundary-aware so /a/bc is NOT under /a/b.
string::with_exe_suffix(&this, suffix: string) -> stringAppend suffix unless it is empty or already present at the end. Used to add a platform executable suffix (e.g. .exe) idempotently.