Builtins

A builtin is a compiler-provided construct prefixed with @.

builtin = "@" IDENT "(" [ builtin_args ] ")" ;
builtin_args = builtin_arg { "," builtin_arg } ;
builtin_arg = IDENT | expression | type ;

The @ prefix distinguishes builtins from user-defined constructs.

Using an unknown builtin name is a compile-time error.

Builtin Kinds

There are two kinds of builtins, distinguished by their syntactic position:

KindPositionPurposeExamples
IntrinsicExpressionProduces a value@dbg, @size_of, @align_of
DirectiveBefore item/statementModifies compiler behavior@allow, @copy

An intrinsic builtin appears where an expression is expected and evaluates to a value. See Intrinsic Expressions for details.

A directive builtin appears before an item or statement and modifies how the compiler processes that construct. See Directives for details.

Directives

A directive is a builtin that modifies the behavior of the immediately following item or statement.

directive = "@" IDENT "(" [ directive_args ] ")" ;
directive_args = directive_arg { "," directive_arg } ;
directive_arg = IDENT ;

A directive MUST be immediately followed by an item or statement. A directive at the end of a file or block without a following construct is a compile-time error.

@allow

The @allow directive suppresses specific compiler warnings for the following item or statement.

@allow accepts one or more warning names as arguments.

The following warning names are recognized:

Warning NameDescription
unused_variableVariable is declared but never used
unused_functionFunction is declared but never called
unreachable_codeCode that can never be executed
unreachable_patternMatch arm pattern that can never match

Using an unrecognized warning name in @allow is a compile-time error.

Suppressing Unused Variable Warnings

When @allow(unused_variable) precedes a let statement, no unused variable warning is emitted for that binding.

fn main() -> i32 {
    @allow(unused_variable)
    let x = 42;  // no warning, even though x is unused
    0
}

When @allow(unused_variable) precedes a function definition, no unused variable warnings are emitted for any bindings within that function.

@allow(unused_variable)
fn example() -> i32 {
    let a = 1;  // no warning
    let b = 2;  // no warning
    0
}

Suppressing Unused Function Warnings

When @allow(unused_function) precedes a function definition, no unused function warning is emitted for that function.

@allow(unused_function)
fn helper() {
    // This function is never called, but no warning is emitted
}

fn main() -> i32 {
    0
}

Suppressing Unreachable Code Warnings

When @allow(unreachable_code) precedes a function definition, no unreachable code warnings are emitted for code within that function.

@allow(unreachable_code)
fn example() -> i32 {
    return 0;
    let x = 42;  // unreachable, but no warning
    x
}

Multiple Warnings

Multiple warning names may be specified in a single @allow directive, separated by commas.

@allow(unused_variable, unreachable_code)
fn example() -> i32 {
    let x = 1;
    return 0;
    let y = 2;
    0
}

Relationship to Underscore Prefix

The underscore prefix convention (e.g., _unused) and @allow(unused_variable) are both valid ways to suppress unused variable warnings. The underscore prefix is more concise for individual variables; @allow is useful when suppressing warnings for an entire function or when the variable name should not have an underscore prefix.

fn main() -> i32 {
    let _x = 42;                    // underscore prefix suppresses warning

    @allow(unused_variable)
    let important_name = 42;        // @allow preserves the meaningful name

    0
}

@copy

The @copy directive marks a struct type as a Copy type.

@copy must appear immediately before a struct definition.

@copy takes no arguments.

@copy
struct Point { x: i32, y: i32 }

fn main() -> i32 {
    let p = Point { x: 1, y: 2 };
    let q = p;  // p is copied, not moved
    p.x + q.x   // both are valid
}

See Move Semantics for the full semantics of @copy structs.