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:
| Kind | Position | Purpose | Examples |
|---|---|---|---|
| Intrinsic | Expression | Produces a value | @dbg, @size_of, @align_of |
| Directive | Before item/statement | Modifies 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 Name | Description |
|---|---|
unused_variable | Variable is declared but never used |
unused_function | Function is declared but never called |
unreachable_code | Code that can never be executed |
unreachable_pattern | Match 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.