Silk

silk/box

One owned heap indirection for recursive data and values whose storage must have a stable size.

When to use

Use Box to break an inline layout cycle, such as a tree node that owns more tree nodes. Use make to allocate, get or getMut to borrow the element, and into to recover it.

Details

A box owns exactly one allocation and one value. Borrowing exposes a one-element slice because Silk can return a slice tied to a parameter but cannot return a bare borrowed value. Dropping the box recursively drops its element; consuming it with into transfers the element and still releases the allocation exactly once.

Gotchas

Ordinary recursive destruction uses the call stack. For a very deep chain, consume links with into in an iterative loop when stack depth matters.

Examples

Store and recover one owned value

import silk.box as Box

import silk.allocator { Allocator }

import silk.effect { Effect }

effect fn build() -> i32
! Allocator.OutOfMemoryError {
  let mut allocator = Allocator.systemAllocatorProvider()
  let creating = Box.make<i32>(42)
    |> Effect.provideMut<Allocator>(&mut allocator)
  let boxed = run creating
  let borrowed = Box.get<i32>(&boxed)
  if borrowed[0] != 42 {
    return 1
  }
  return Box.into<i32>(move boxed)
}

effect fn recover(error: Allocator.OutOfMemoryError) -> i32 {
  return 0
}

pub fn main() -> i32 {
  return run Effect.catchAll(build(), recover)
}

Import as Box with import silk.box.

Public declarations: 7.

Vacant

pub struct Vacant

A marker for a box whose element has been transferred to its caller.

Occupied

pub struct Occupied

A marker for a box that owns one initialized element.

Box

pub struct Box<T>

Owns one heap-allocated T and releases both the value and its allocation on drop.

make

pub effect fn make<T>(value: T) -> silk/box.Box<T> ! OutOfMemoryError ? &mut Allocator

Moves one value into a new box with storage for exactly one element.

Details

The returned box owns the value and the allocation. Allocation failure produces OutOfMemoryError and does not produce a partial box.

get

pub fn get<T>(self: &silk/box.Box<T>) -> &[T]

Borrows the held value as a shared slice of length one.

Details

The slice borrows the box and remains valid only for the lexical borrow.

getMut

pub fn getMut<T>(self: &mut silk/box.Box<T>) -> &mut [T]

Borrows the held value as an exclusive slice of length one.

Details

The slice permits mutation of the element and remains valid only for the lexical borrow.

into

pub fn into<T>(self: silk/box.Box<T>) -> T

Consumes the box, returns its owned value, and releases its allocation.

Implementation Drop for silk/box.Box<T>

impl Drop for silk/box.Box<T>

On this page