Unchecked Code Syntax
This section describes the syntax for unchecked code constructs.
Unchecked Functions
A function MAY be marked with the @mark(unchecked) directive to indicate that calling it requires a checked block (ADR-0088). The legacy unchecked hard-keyword spelling has been retired.
function = directive* [ "pub" ] "fn" IDENT "(" [ params ] ")" [ "->" type ] "{" block "}" ;
A call to an @mark(unchecked) function is a compile-time error unless it appears inside a checked block.
@mark(unchecked)
fn dangerous_operation() -> i32 {
42
}
@mark(unchecked)
pub fn public_dangerous() -> i32 {
0
}
Checked Blocks
A checked block is an expression that enables unchecked operations within its body.
checked_expr = "checked" "{" block "}" ;
A checked block evaluates its body and returns the value of the final expression. The type of a checked block is the type of its body expression.
Pointer intrinsics (@raw, @raw_mut, @ptr_read, @ptr_write, @ptr_offset, @ptr_to_int, @int_to_ptr, @null_ptr, @is_null, @ptr_copy, @syscall) are compile-time errors unless they appear inside a checked block.
fn main() -> i32 {
let x = checked {
let a = 10;
let b = 32;
a + b
};
x
}
Raw Pointer Types
Gruel provides two raw pointer types for low-level memory access:
Ptr(T)- a pointer to immutable data of typeTMutPtr(T)- a pointer to mutable data of typeT
Ptr and MutPtr are built-in compiler-recognized type constructors; they share the call-style surface form with comptime-generic user types (e.g. Vec(T)), but their lowering is hard-wired in the compiler. See ADR-0061. Originally introduced as ptr const T / ptr mut T keyword syntax (ADR-0028); that surface form has been replaced.
ptr_type = ( "Ptr" | "MutPtr" ) "(" type ")" ;
fn takes_ptr(p: Ptr(i32)) -> i32 { 0 }
fn takes_mut_ptr(p: MutPtr(i32)) -> i32 { 0 }
@mark(unchecked)
fn get_ptr() -> Ptr(i32) { @panic() }