Value Model

Value & Reference Model

Status: stable reference

Concrete uses a strict value/reference model with linear types by default.

For the full safety model (capabilities, trusted boundaries, Unsafe), see SAFETY. For FFI and trust boundaries, see FFI.

Value Categories

TypeSemanticsDefaultNotes
Primitives (Int, i32, bool, etc.)Value, CopyCopyAlways passed by value
&TShared referenceCopyImmutable borrow
&mut TExclusive referenceLinearMutable borrow, consumed on use
*mut T / *const TRaw pointerCopyRequires Unsafe capability
Heap<T>Owned heap pointerLinear-> field access, must be freed
StructsValueLinearOpt-in Copy via marker
EnumsValueLinearOpt-in Copy via marker
NewtypesSame as inner typeInheritsnewtype UserId = Int is Copy because Int is Copy
Function pointersValueCopyNo closures

Copy vs Linear

  • Copy types can be used multiple times. Primitives, &T, raw pointers, and function pointers are always Copy. Structs and enums opt in with a Copy marker.
  • Linear types must be consumed exactly once. All structs and enums are linear by default. Branches must agree on consumption. Loops cannot consume linear variables from outer scope.

Newtype

newtype UserId = Int;       // Copy (inner is Copy)
newtype OwnedBuf = String;  // Linear (inner is linear)
newtype Wrapper<T> = T;     // Inherits from T
  • Wrap: UserId(42) — type-checked constructor
  • Unwrap: id.0 — extracts inner value
  • No implicit conversions: UserId and Int are distinct types
  • Zero-cost: Erased at compile time, no runtime representation

Layout Attributes

#[repr(C)]

C-compatible struct layout. Required for FFI.

#[repr(packed)]

No padding between fields. Alignment forced to 1.

#[repr(C, packed)]
struct Header { version: u8, flags: u16, length: u32 }
// sizeof = 7 (1 + 2 + 4, no padding)

#[repr(align(N))]

Minimum alignment override (N must be a power of 2).

#[repr(C, align(16))]
struct Aligned { x: i32 }
// sizeof = 16 (rounded up), alignof = 16

packed and align(N) cannot be combined on the same struct.

Intrinsics

  • sizeof::<T>() — compile-time byte size of T (returns Uint)
  • alignof::<T>() — compile-time alignment of T (returns Uint)