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
| Type | Semantics | Default | Notes |
|---|---|---|---|
Primitives (Int, i32, bool, etc.) | Value, Copy | Copy | Always passed by value |
&T | Shared reference | Copy | Immutable borrow |
&mut T | Exclusive reference | Linear | Mutable borrow, consumed on use |
*mut T / *const T | Raw pointer | Copy | Requires Unsafe capability |
Heap<T> | Owned heap pointer | Linear | -> field access, must be freed |
| Structs | Value | Linear | Opt-in Copy via marker |
| Enums | Value | Linear | Opt-in Copy via marker |
| Newtypes | Same as inner type | Inherits | newtype UserId = Int is Copy because Int is Copy |
| Function pointers | Value | Copy | No 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 aCopymarker. - 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:
UserIdandIntare 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 ofT(returnsUint)alignof::<T>()— compile-time alignment ofT(returnsUint)