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 type T
  • MutPtr(T) - a pointer to mutable data of type T

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() }