requires — Gating Capabilities
requires declares a mandatory dependency for the module. The compiler checks
the capability table of the active target and, if any clause fails, aborts the
build with a clear diagnostic pointing to the directive — no code ever runs
without the required capabilities.
Known capabilities include backend.{vm,native,wasm},
platform.{posix,linux,macos,windows}, feature.{fs,net,process,signals,threads, gpu,bigint}, and version >= X.Y. Multiple clauses can be stacked: all
must be satisfied.
The simplest form requires the module to run only on the VM backend, with access to the file system, and on a minimum language version:
Three requires in sequence; the compiler validates them before any fn.
// Feature: `enable` and `requires` directives
// Syntax: `enable <feature>;` / `requires <capability>;`
// When to use: gate a module on backend capabilities (FS, signals,
// threads, GPU, ...) or platform (POSIX vs Windows). Build fails
// early with a clear message instead of panicking at runtime.
//
// See `specs/enable-requires-directives.md` for the full specification.
requires backend.vm
requires feature.fs
requires version >= 0.1
// `enable` activates optional language features. Unknown features emit
// a warning (forward-compat); enabling a feature unsupported on the
// current backend is a hard error.
//
// enable simd // available only on backend.native / .wasm
// enable signals // available on backend.vm / .native
//
// Diretivas devem aparecer no topo do arquivo, antes de `use`, `fn`,
// `struct`, etc. Diretiva após declaração → E_DirectiveNotAtTop.
fn main() {
print("directives validated at build time; nothing to do in runtime")
}
// Run:
// zolo run 01-enable-requires.zolo
// → directives validated at build time; nothing to do in runtime
//
// Try changing `requires backend.vm` to `requires backend.native` —
// the build will now fail with E_CapabilityMissing pointing at the
// directive, before any of your code runs.
When the module depends on multiple features together — for example, fs and
process — each gets its own line. Reaching main already means all of them
are available, with no need for runtime fallbacks:
requires feature.fs + requires feature.process guarantee both before execution.
// Feature: gating a module on multiple capabilities + a minimum
// language version.
//
// `requires` can be stacked — every clause must hold or the build
// aborts with `error[D0002]`. Common gates:
// - `requires backend.{vm,native,wasm}`
// - `requires platform.{posix,linux,macos,windows,wasm}`
// - `requires feature.{fs,net,process,signals,threads,gpu,...}`
// - `requires version >= 0.1` // monotonic, never expires
//
// See specs/enable-requires-directives.md for the full capability table.
requires version >= 0.1
requires feature.fs
requires feature.process
use std::fs
use std::process
fn main() {
// Reaching this line guarantees fs + process are available on the
// active target — no runtime fallback needed.
print("pid: {process.pid()}")
let cwd_ok = fs.exists(".")
print("cwd writable: {cwd_ok}")
}
// Try editing the file to add `requires backend.wasm` — building for
// the VM target should now fail with a clear diagnostic instead of
// crashing at runtime.
Challenge
Add requires backend.wasm to the file 02-platform-gating.zolo and try
compiling for the VM target. What appears in the error message? Which capability
is missing?