Region Scopes¶
Overview¶
Region scopes manage lifetime through implicit region creation and destruction. All allocations made in a region are destroyed when that region exits. Region ownership is tracked by allocation provenance, not by lexical scope nesting.
Syntax¶
$ {
let p = alloc Point;
doSomething(p);
}
$ {
let a = alloc Point;
$ {
let b = alloc Point;
doSomething(b);
}
}
extern ^ function makePoint(): &Point;
export function main(): int {
$ {
let p = makePoint();
doSomething(p);
}
}
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, break, and continue. 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. Moving a handle from an outer lexical scope inside a nested region MUST be permitted if all move and lifetime constraints are satisfied. Nested regions MUST be destroyed in reverse order of creation.
Handle Lifetime¶
A handle MUST NOT outlive the region in which it was allocated. A handle MUST NOT be moved into storage that may outlive its allocation region. A handle allocated in an inner region MUST NOT be moved to an outer region, returned to a caller whose ambient region does not include that allocation, or otherwise exposed beyond its allocation region lifetime.
Handle-Containing Struct Lifetime¶
A struct type that transitively contains owned handles MUST follow the same region lifetime constraints as direct handle values. A value of such a type MUST NOT be moved into storage that may outlive any owned handle it contains. The compiler MUST enforce this constraint at compile time.
Region-Qualified Function Interaction¶
Region-qualified functions (^ function) MUST execute with a caller-provided ambient region context. A region-qualified function MAY return a value that transitively contains an owned handle only when every owned handle in the returned value originates from the caller ambient region context, not from a nested region created inside the callee.
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.