Attributes
Attributes are compiler-known metadata: they flip flags the compiler reads, or (for contracts) emit the same checks assert uses. They never run user logic or expand into macros. An unknown attribute is E0354.
#[test]: register a test function
#[test]
fn it_adds() {
let r: i32 = add(2, 3);
assert r == 5;
}
Run with cpc test. The assert intrinsic sets a failure flag in a test build and traps in a regular build.
Function contracts: #[requires] and #[ensures]
Machine-checked preconditions and postconditions on a fn or method. Each argument is a pure bool expression; the compiler emits it as an assert (traps on violation; test builds report). See Functions.
#[requires(n > 0)]
#[ensures(result >= n)]
fn bump(n: i32) -> i32 { return n +% 1; }
A non-bool or impure expression is E0924. Naming result on a function that returns nothing is E0928.
#[repr(C)], packed layout, bitfields, and #[link_name]
Layout and symbol control for FFI. Covered on the FFI page:
#[repr(C)]promises platform C-ABI layout for a struct or union that crosses anextern fnboundary.#[repr(C, packed)]/#[repr(C, packed = N)]remove padding, or cap field alignment atN.#[bits(N)]on an integer field packs a C bitfield.#[link_name]binds one C symbol under several typed shapes.#[repr(u8)]…#[repr(i64)]/#[repr(C)]pin a payload-free enum's integer width.
Loop hints: #[unroll(N)] and #[vectorize_width(N)]
Statement-level attributes that flow through to LLVM's loop optimizer as !llvm.loop metadata. Apply them to a while, loop, or for. N is a literal in [1, 256].
#[unroll(4)]
while i < n {
sum = sum + buf[i as usize];
i = i +% 1;
}
#[vectorize_width(8)]
for i in 0..count {
out[i as usize] = a[i as usize] * b[i as usize];
}
They are marginal for general code but load-bearing for the tight inner loops the compiler does not vectorize well by default.
#[inline]: inlining control
A function- or method-level attribute, in three forms:
#[inline]becomes LLVMinlinehint. Only the optimizer acts on it, so it matters at--releaseand is a no-op at debug-O0.#[inline(always)]becomesalwaysinline. It inlines even at-O0and past LLVM's cost threshold, the lever for hot kernels built from small over-threshold helpers.#[inline(never)]becomesnoinline. It pins a call boundary for cold paths or code-size control.
These are pure hints with no behavioural change, so reach for them only on measured hot or deliberately cold paths.
Real-time contracts
#[no_alloc], #[no_block], #[bounded_recursion], #[max_stack(N)], and the #[realtime] bundle are compiler-verified contracts, not optimizations. They are documented in full on the Real-time page.
#[naked]: no prologue or epilogue
A function-level attribute for a function whose body is entirely inline assembly and supplies its own ABI handling. It is covered on the Inline assembly page.
Doc comments
/// Returns the square of x.
fn sq(x: i32) -> i32 { return x *% x; }
/// comments are doc comments, and cpc test picks up fenced code blocks inside them as doctests.