Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@ per-PR journal is preserved in
[`docs/archive/HANDOFF-2026-07-25.md`](docs/archive/HANDOFF-2026-07-25.md).

_Last updated: 2026-08-05._ The C-B borrow/ownership capability is complete
through L2e. Direct, captured, imported, and function-value returns preserve
exact owner provenance; recursively Move returns carry a path-selected cleanup
bit; and shared/exclusive parameters preserve caller ownership, replacement,
generation invalidation, and whole/per-unit ABI parity. No public `pkg.db`
surface exists yet.
through L2e, F-A native resources is complete through L3, and F-B explicit
region materialization is complete through L4 and L6. Direct, captured,
imported, and function-value returns preserve exact owner provenance;
recursively Move returns carry a path-selected cleanup bit; shared/exclusive
parameters preserve caller ownership, replacement, generation invalidation,
and whole/per-unit ABI parity; package-defined native resources have nominal
identity, checked refs/views, producer-owned cleanup thunks, and exactly-once
Drop; and named regions now support explicit recursive cloning plus chunked
`RegionPlain` array construction without a hidden heap vector. No public
`pkg.db` surface exists yet.

The remaining compiler plan uses consumer-complete capability waves rather
than one PR per dormant acceptance cell:

```text
C-A canonical callable closure complete through c3
C-B borrow/ownership closure complete through L2e
F-A native resources complete through L3
F-B region materialization complete through L4 + L6

next independent waves:
F-A native resources L3
F-B region materialization L4 + L6
F-C static artifacts L5

after F-A/F-B, while also waiting for F-C:
Expand Down
3 changes: 3 additions & 0 deletions crates/align_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ pub enum ExprKind {
Loop(Block),
/// `arena { ... }` — a region whose allocations are freed in bulk at block end.
Arena(Block),
/// `arena name { ... }` — the same region with an explicit, scope-limited `region`
/// capability bound as `name` for allocation in ordinary callees.
NamedArena { name: Ident, block: Block },
/// `unsafe { ... }` — a block in which `raw.*` operations (raw allocation, unchecked casts,
/// manual free) are permitted. A plain marker block otherwise (no runtime effect); a function
/// containing one is inferred impure (so it can never be a `par_map` callee).
Expand Down
478 changes: 447 additions & 31 deletions crates/align_codegen_llvm/src/lib.rs

Large diffs are not rendered by default.

24 changes: 17 additions & 7 deletions crates/align_codegen_llvm/src/runtime_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,21 @@ pub(super) fn runtime_abi(key: RuntimeKey) -> RuntimeAbi {
symbol: "align_rt_array_builder_new",
shape: RuntimeAbiShape::A43,
},
RuntimeKey::ArrayBuilderNewIn => RuntimeAbi {
key,
symbol: "align_rt_array_builder_new_in",
shape: RuntimeAbiShape::A45,
},
RuntimeKey::ArrayBuilderPush => RuntimeAbi {
key,
symbol: "align_rt_array_builder_push",
shape: RuntimeAbiShape::A66,
},
RuntimeKey::ArrayBuilderPushBytes => RuntimeAbi {
key,
symbol: "align_rt_array_builder_push_bytes",
shape: RuntimeAbiShape::A72,
},
RuntimeKey::ArrayBuilderPushStr => RuntimeAbi {
key,
symbol: "align_rt_array_builder_push_str",
Expand Down Expand Up @@ -1694,15 +1704,15 @@ pub(super) fn runtime_abis() -> impl Iterator<Item = RuntimeAbi> {
}

pub(super) fn validate_registry() -> Result<(), String> {
if RuntimeKey::ALL.len() != 281 || keyed_runtime_abis().len() != 281 {
if RuntimeKey::ALL.len() != 283 || keyed_runtime_abis().len() != 283 {
return Err("runtime ABI registry invariant: key-count".to_string());
}
if runtime_abis().count() != 286 {
if runtime_abis().count() != 288 {
return Err("runtime ABI registry invariant: base-count".to_string());
}

let mut keys = HashSet::with_capacity(RuntimeKey::ALL.len());
let mut symbols = HashSet::with_capacity(286);
let mut symbols = HashSet::with_capacity(288);
for abi in keyed_runtime_abis() {
let key = abi
.runtime_key()
Expand Down Expand Up @@ -2960,17 +2970,17 @@ mod tests {
assert_eq!(UNKEYED_RUNTIME_KEYS.map(|key| key as u8), [0, 1, 2, 3, 4]);
validate_registry().unwrap();
let rows: Vec<_> = runtime_abis().collect();
assert_eq!(rows.len(), 286);
assert_eq!(rows.len(), 288);
assert_eq!(
rows.iter().map(|row| row.key).collect::<HashSet<_>>().len(),
286
288
);
assert_eq!(
rows.iter()
.map(|row| row.symbol)
.collect::<HashSet<_>>()
.len(),
286
288
);
for (key, row) in RuntimeKey::ALL.into_iter().zip(keyed_runtime_abis()) {
assert_eq!(row.key, RuntimeAbiId::Keyed(key));
Expand Down Expand Up @@ -3000,7 +3010,7 @@ mod tests {
fn runtime_abi_extern_type_matrix_is_exact_for_every_row_and_ordinal() {
let ctx = inkwell::context::Context::create();
let rows: Vec<_> = runtime_abis().collect();
assert_eq!(rows.len(), 286);
assert_eq!(rows.len(), 288);

for row in rows {
let symbol = row.symbol;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ key|ArrayBuilderFreeStrings|array_builder_free_strings|declare void @align_rt_ar
key|ArrayBuilderFreeStringsStack|array_builder_free_strings_stack|declare void @align_rt_array_builder_free_strings_stack(ptr)
key|ArrayBuilderInitStack|array_builder_init_stack|declare ptr @align_rt_array_builder_init_stack(ptr, i64)
key|ArrayBuilderNew|array_builder_new|declare noalias ptr @align_rt_array_builder_new(i64) #0
key|ArrayBuilderNewIn|array_builder_new_in|declare noalias ptr @align_rt_array_builder_new_in(ptr, i64, i64) #2
key|ArrayBuilderPush|array_builder_push|declare void @align_rt_array_builder_push(ptr, i64)
key|ArrayBuilderPushBytes|array_builder_push_bytes|declare void @align_rt_array_builder_push_bytes(ptr, ptr)
key|ArrayBuilderPushStr|array_builder_push_str|declare void @align_rt_array_builder_push_str(ptr, ptr, i64)
key|Base64Decode|base64_decode|declare i32 @align_rt_base64_decode(ptr, i64, ptr)
key|Base64Encode|base64_encode|declare { ptr, i64 } @align_rt_base64_encode(ptr, i64)
Expand Down
Loading
Loading