pragmas and attributes
α1○ compiler-directives○ intrinsics◌ derive-attributes (α2)
pragmas and attributes
ferrule has two kinds of metadata annotations, plus a small set of derive-specific attributes. the set is deliberately small and not user-extensible.
#[...]: compiler directives
fixed, known set. not user-extensible. these affect codegen but are not part of the type system and not visible to other code.
#[entry] // bare metal entry point
#[interrupt] // interrupt handler
#[interrupt(priority = 3)] // with parameters
#[inline] // suggest inlining
#[inline(always)] // force inlining
#[inline(never)] // prevent inlining
#[cold] // unlikely code path
#[align(64)] // alignment requirement
#[section(".fast_ram")] // linker section placement
#[deprecated("use foo()")] // deprecation warning
#[test] // test function
#[link("libssl")] // link against library@: intrinsics
compile-time functions built into the compiler:
@sizeOf<T>() // size in bytes
@alignOf<T>() // alignment
@typeInfo<T>() // type reflection
@bitCast<T>(val) // reinterpret bits
@compileError(msg) // compile-time error
@embedFile(path) // embed file contents as bytes
@fieldNames<T>() // field names of a recordderive-specific attributes (α2)
only valid inside derive(...) blocks:
type ApiResponse = derive(Codec<Json>) {
@rename("user_id")
id: u64,
@skip_if_none
metadata: Metadata?,
@flatten
common: CommonFields,
}@rename, @skip, @flatten, @default, @skip_if_none are not general-purpose attributes. they only work in derive context.
no general-purpose attribute system
ferrule deliberately avoids Java-style annotations or Rust-style arbitrary proc macro attributes. the set of directives and intrinsics is small and known. this keeps the language predictable and tooling simple.