machdocs
Home GitHub

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.

ShapeMeaning
$mach.* / $project.* / $bin.*rooted compiler-owned read (compiler to developer)
$sym(args)comptime function call (an intrinsic)
$if, $orcomptime control flow
Note

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:

ReadValue
$project.idproject id, from [project]
$project.nameproject name
$project.descriptionproject description
$project.versionwhole version string, e.g. "2.0.0"
$project.version.majormajor version component (folded integer)
$project.version.minorminor version component
$project.version.patchpatch version component
$project.target.osselected target os string, e.g. "linux"
$project.target.archselected target arch string, e.g. "x86_64"
$project.target.abiselected target abi string, e.g. "sysv64"
$bin.namethe 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
Note

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.

Implementation status

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.

Diagnostic

comptime parameters are referenced without $; comptime paths are rooted: $mach, $project, $bin

Not in the channel

See also

  • Intrinsics - $size_of, $assert, and the comptime call set
  • Control flow - $if / $or gates over these reads
  • Decorators - #[...] codegen attributes
  • Manifest - the [project] and target stanzas feeding $project.*