The comptime channel
The $ prefix opens the comptime channel, the compiler-owned namespace a program reads at compile time. It is read-only: $ selects and expands, it never executes or mutates. Conditional compilation, intrinsics, and target queries all ride one of its shapes.
The shapes
The parser tells the shapes apart by structure, so a name never has to be looked up to know what kind of read it is.
| Shape | Meaning |
|---|---|
$mach.* / $project.* / $bin.* | rooted compiler-owned read (compiler to developer) |
$sym(args) | comptime function call (an intrinsic) |
$if, $or | comptime control flow |
$<root>.<path>reads into a compiler-owned tree. The rootsmach,project, andbinare reserved at the top of$; user symbols cannot collide with them.$ident(args)is a comptime call; the closed compiler-intrinsic set lives here.$if/$orare comptime branches, structurally distinct from runtimeif/or.
Per-declaration codegen attributes (symbol rename, library pin, inline, align, section) are written as #[...] decorators, not $-comptime shapes. See Decorators.
Compiler-owned roots
Three rooted trees carry the read-only facts a build exposes. $mach.* (the active build and compiler identity) has its own section below; $project.* and $bin.* read project metadata and the current artifact, one member at a time:
| Read | Value |
|---|---|
$project.id | project id, from [project] |
$project.name | project name |
$project.description | project description |
$project.version | whole version string, e.g. "2.0.0" |
$project.version.major | major version component (folded integer) |
$project.version.minor | minor version component |
$project.version.patch | patch version component |
$project.target.os | selected target os string, e.g. "linux" |
$project.target.arch | selected target arch string, e.g. "x86_64" |
$project.target.abi | selected target abi string, e.g. "sysv64" |
$bin.name | the artifact (build unit) being built |
The $project.target.* reads carry the manifest's declared string spellings, distinct from the numeric tags used for $mach.build.* comparison. The flat $project.version string and its structured major, minor, and patch components are all available.
val ver: str = $project.version; # "2.0.0", from [project].version
$if ($project.target.os == "windows") { ... } # the declared os string
A root field the manifest does not declare (for example $project.description or $bin.name on a v1 manifest with no artifact stanza) reports the read as unavailable rather than folding to an empty string.
The $mach.* namespace
The $mach.* subtree is the compiler's view of the world: the resolved build context, the compiler identity, and source position. Every read is a comptime constant.
Live today: $mach.build.os, $mach.build.arch, $mach.build.abi, $mach.build.pointer_width, $mach.build.mode, the tag tables, $mach.version (with its components), $mach.compiler.name, and $mach.compiler.version. Reserved stubs: $mach.build.timestamp, $mach.build.host, $mach.build.git.*, $mach.project.*, and $mach.source.*. Reading a stub is a compile error ("not yet available").
$mach.build.* - what we build for
The resolved active build's facts. os, arch, abi, and mode share the numeric tag space of $mach.{os,arch,abi,mode}.*, so a comparison is a plain integer compare.
$mach.build.os # compared against $mach.os.* tags
$mach.build.arch # compared against $mach.arch.* tags
$mach.build.abi # compared against $mach.abi.* tags
$mach.build.pointer_width # integer count of bytes
$mach.build.mode # compared against $mach.mode.* tags
A bare $mach.build.<name> that names none of the reserved facts resolves to the manifest comptime define of that name, or is a compile error when no such define was declared.
Version and compiler identity
$mach.version # the version string, e.g. "2.0.0"
$mach.version.major # integer component (minor, patch too)
$mach.compiler.name # compiler identity
$mach.compiler.version # same value as $mach.version
Tag tables
The $mach.{os,arch,abi,mode}.* tables exist for path-value comparison against the resolved build. The lists are closed and grow only when backend support lands; an unrecognized tag name is a compile error, never a silent fold.
$mach.os.linux
$mach.os.darwin
$mach.os.windows
$mach.os.freestanding
$mach.arch.x86_64
$mach.arch.aarch64
$mach.abi.sysv
$mach.abi.win64
$mach.abi.aapcs64
$mach.mode.debug
$mach.mode.release
Comparing tags
Tag comparisons are path-value, with no .id suffix or unwrapping. Both sides share one numeric space, so the comparison is an ordinary integer compare.
$if ($mach.build.os == $mach.os.linux) { ... }
$if ($mach.build.arch == $mach.arch.x86_64) { ... }
Folding into runtime values
A $mach.* read can initialize a runtime binding; the compiler folds the right-hand side at compile time.
pub val IS_LINUX: u8 = $mach.build.os == $mach.os.linux;
pub val COMPILER: *u8 = $mach.compiler.name;
The bare $ident is rejected
A standalone bare $ident such as $mode or $foo is none of the shapes above. A comptime parameter is referenced by its bare name (no $); every comptime path is rooted. The rule applies identically in a $if gate and in value position, with sema and lowering deferring to the evaluator's single verdict.
comptime parameters are referenced without $; comptime paths are rooted: $mach, $project, $bin
Not in the channel
- No reflection via a
$<Type>.*subtree. Types are not first-class comptime values. - No decl-attached prefix sugar;
$inline pub fun ...does not exist. Use#[...]decorators instead. - No comptime function definitions, and no comptime loops.
- No bare
$ident.
See also
- Intrinsics -
$size_of,$assert, and the comptime call set - Control flow -
$if/$orgates over these reads - Decorators -
#[...]codegen attributes - Manifest - the
[project]and target stanzas feeding$project.*