ADR 0003 — M3 heap types are built in, ahead of general generics
- Status: Accepted (project owner, 2026-10-22, when starting M3: "Built-in types")
- Scope: how M3 provides
Result,Boxand allocators before generics (M6), interfaces (M6) and raw pointers /unsafe(M8) exist.
Context
The M3 acceptance examples (language-spec.md Ex4, Ex5, Ex11, Ex14) use Result<T, E>, Box<T, A>, T?, a generic function with an interface bound (createUser<A: Allocator>), StringView and integer methods such as checkedMul. The Allocator interface in memory-model.md §3.2 uses unsafe fn and *mut u8. Generics and interfaces are scheduled for M6 and raw pointers for M8 (roadmap.md).
Decision
Result<T, E>andBox<T, A>are compiler-known generic types, likeSlice<T>in M2. Each instantiation is monomorphised in C. User-declared generic types and functions remain M6.- Allocators are built-in, free-standing types:
SystemHeapandFailingAllocator. Their values are zero-sized.AllocErroris a built-in enum. - The
Allocatorinterface stays as specified inmemory-model.md§3.2. User-defined allocators, and generic functions over allocators (Ex5 as written), come with interfaces in M6. M3 runs Ex5 with a concrete allocator type. - Optionals (
T?,null,?on optionals) stay in M6 with the other library types. Ex11 is run in an adapted form withoutStringView,checkedMulandokOr. - When M6 adds generics,
ResultandBoxshould become library types with the same surface syntax and the same C layout, so programs written for M3 keep compiling.
Consequences
- M3 stays small: no generic type checking and no interface resolution.
- The acceptance criteria are met with Ex4, Ex14 and adapted Ex5/Ex11 (
milestone-3.md); the deferred parts of Ex5 and Ex11 are tracked for M6. - The built-in surface (
Ok,Err,Box.create,Box.createIn,?,!) is the one M6 must preserve.