Skip to content

Region Scopes

Overview

Region scopes manage the lifetime of allocated objects through implicit region creation and destruction. All objects allocated within a region are destroyed when the region exits.

Syntax

$ {
    let p = alloc Point;
    doSomething(p);
}

$ {
    let a = alloc Point;
    $ {
        let b = alloc Point;
        doSomething(b);
    }
}

with outerHandle {
    $ {
        doSomething(outerHandle);
    }
}

Rules

Region Creation

Upon entering a $ { ... } scope, larol_region_create() MUST be called implicitly (which returns a opaque 64 bit region handle). The resulting region handle MUST be stored in a compiler-managed variable with an inaccessible internal name. This variable MUST NOT be referenceable by user code. If region creation fails, the runtime implementation will treat this as a fatal error.

Region Destruction

Directly before exiting a $ { ... } scope, larol_region_destroy(region) MUST be called implicitly. This applies to all exit paths including normal block exit, return, and break. If region destruction fails, the runtime implementation will treat this as a fatal error.

Non-Empty Body

A region scope MUST contain at least one statement. An empty $ { } MUST NOT be permitted.

Nested Regions

Nested region scopes MUST be permitted. Direct access to handles allocated in an outer region MUST be permitted. The with keyword is only required when a handle from an outer scope needs to be moved within the nested region. Nested regions MUST be destroyed in reverse order of creation.

Handle Lifetime

A handle MUST NOT outlive the region in which it was allocated. Moving a handle out of any scope, whether via return or by moving it into a handle owned by an outer scope, MUST NOT be permitted. Transferring handles into an inner scope MUST be permitted using the with keyword. Transferring handles from an inner scope to an outer scope via with (or any other method) MUST NOT be permitted.

Handle-Containing Struct Lifetime

A struct type that transitively contains handle members MUST NOT outlive the region in which it was allocated. A value of such a struct type MUST NOT be returned from a function, stored in a struct member, or assigned to a variable in an outer scope. The compiler MUST enforce this constraint at compile time.

With and Regions

Within region scopes, the with keyword MUST be permitted for use to transfer a handle before that handle may be moved within a nested region scope. Direct access to outer handles without with MUST be permitted; with is only required when a move within a nested scope is intended.

Capability Lifetime

The compiler MUST ensure that no capability derived from a handle in a region is still active when that region is destroyed. Producing a capability that would outlive its source region MUST be a compile-time error.