Skip to content

Implement the settled/roaming memory model - #177

Merged
TheLazyCat00 merged 6 commits into
mainfrom
claude/loving-pascal-0m6cxi
Oct 5, 2026
Merged

TheLazyCat00 merged 6 commits into
mainfrom
claude/loving-pascal-0m6cxi

Conversation

@TheLazyCat00

Copy link
Copy Markdown
Member

Brings the compiler from spec b0675d6 up to zane-lang/spec#212, zane-lang/spec#214 and zane-lang/spec#216, plus the follow-ups in the spec PR on the branch of the same name.

Language

  • ^T (roaming owner). It is written on locals, parameters, return types and abort types.
    • A bare reference-type parameter borrows, ^T takes the owner, and &T takes a reference. this is always a borrow.
    • A bare reference-typed return or abort type is an error.
    • A type parameter's introduction carries the mode: x ^T Type, x &T Type.
  • Moves. Only a roaming symbol, a field of one, a ^T verb result or a case form moves. Moving a field leaves its root partly spent until the field is refilled. A ^T parameter's scope is the body's top block.
  • References. A reference is made only from a settled place, through struct fields and ArrayRef elements. A declared subscript is followed to the place its body projects.
  • Wrong-kind type arguments are reported at their origin (generics §3.6). That covers a reference type reaching a value mould, and now also a value type filling an &T.
  • New intrinsic @primitives$ArrayRef<T, n>, with a literal constructor, .fill(n, lambda) and element access.
  • @primitives$String is now a value type. print borrows its text, which closes the old print divergence.
  • push takes ^T.
  • Analyses. A new states.ml decides whether a place is settled, roaming or borrowed. moves.ml is rewritten. guests.ml is renamed references.ml and owners.ml is renamed scopes.ml, and diagnostics use the new vocabulary.

Runtime and lowering

  • Anchors, tethers, backpointers and floating are gone, including runtime/anchor.c. A reference is a raw pointer.
    • The spec describes a 32-bit segmented offset instead; that difference is recorded in docs/design/lowering.md §9.
  • Every overwrite happens in place and reuses the blocks of boxed members, so references into them stay valid.
  • A block is relocated only when its region does not outlive the destination.
  • A ^T argument is passed by value and held in the callee's top arena.

Grammar

  • New CARET token, ^T type atoms, and ^/& before an inline introduction.
  • Parser conflict census: 62 states with GLR, 55 with stock Menhir. docs/ambiguity/proof-obligations.md is updated.

Tests

  • just test passes: compiler, grammar, ambiguity tools and grammar generation.
  • just check-file-sizes warns only that lib/cgt/lower.ml is 1519 lines.
  • just verify-grammar (Lean) was not run locally, because lake is not installed in the environment.
  • Codegen tests:
    • hosts and guests are renamed to owners and settled, and rewritten.
    • New test: arrayrefs.
    • references now covers a generic &T Type holder that sees an in-place overwrite.
    • Every .out is all "yes".
  • Rejection tests: rewritten for the new rules, plus a new marks.zn for marker placement, result modes, overloads by mode, and wrong-kind ^/& arguments.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ArFxFkp985vTC6aHAAxp82


Generated by Claude Code

claude added 4 commits October 5, 2026 16:15
Syntax: a `^` token, `^T` as a type atom beside `&T`, and `x ^T Type` for an
inline type parameter that takes an owner. Six new conflict states, all in
the existing `<` declared-operator family; the ledger and census record them.

Semantics: `Ty.Roaming` beside `Ty.Reference` (was `Ty.Guest`). `^` only on a
local, a parameter or a return type, only on a reference type; a bare
reference-typed result or abort type is an error, as is a marker on `this`.
A new `states.ml` decides whether a place is settled, roaming, borrowed,
contingent or fresh, and the analyses read it: a move takes only a roaming
symbol, a field of one (leaving the root partly spent), a verb result or a
case form; a reference is minted only from a settled place, through struct
fields and `ArrayRef` elements, and a declared subscript is followed to its
projection; a bare reference-type parameter and `this` are borrows; a `^T`
parameter is scoped to the body's top block. `guests.ml` and `owners.ml`
become `references.ml` and `scopes.ml`, and diagnostics use the owner /
reference / scope vocabulary. A wrong-kind type argument is reported at its
origin (generics.md §3.6). `@primitives$ArrayRef<T, n>` with its literal
constructor, `fill`, and subscript. `@primitives$String` is a value type,
`print` borrows its text and `push` takes `^T`, which closes the old `print`
divergence.

Lowering and runtime: a reference is the settled owner's address, so the
anchor pool, backpointers, forwarders and floating are gone (anchor.c is
removed) and a reference-type instance is its members alone. A `^T`
argument is moved into the callee and held in its body's arena; a borrow is
passed by address. Every overwrite is in place, writing into each boxed
member's existing block, and a block relocates only when its owner escapes.
`ArrayRef` lowers as `Array` does, with `fill` a counted loop.

Fixtures and goldens are rewritten in the new model (`hosts` and `guests`
become `owners` and `settled`), with new codegen, runtime and reject cases
for in-place overwrites observed through references, `ArrayRef`, takes,
partial spending and the type-level rules. Design docs describe the new
model and record a reference as a 64-bit address rather than a segmented
offset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ArFxFkp985vTC6aHAAxp82
A type parameter's introduction carries the passing mode (spec generics.md
§3.2): `x &T Type` takes a reference, inferred from the place it is minted
from. `&` marks only a reference type, so a value type that fills an `&T`
written over a type parameter, on a field or a verb's parameter, is a
wrong-kind argument reported at its origin (generics.md §3.6).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ArFxFkp985vTC6aHAAxp82
@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 118 files, which is 18 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Repository: zane-lang/coderabbit/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 733f08ad-5c66-4e38-8baf-81148998dbbd
📥 Commits

Reviewing files that changed from the base of the PR and between 14e70c5 and e381975.

⛔ Files ignored due to path filters (9)
  • tests/codegen/golden/arrayrefs.out is excluded by !**/*.out
  • tests/codegen/golden/boxes.out is excluded by !**/*.out
  • tests/codegen/golden/owners.out is excluded by !**/*.out
  • tests/codegen/golden/references.out is excluded by !**/*.out
  • tests/codegen/golden/settled.out is excluded by !**/*.out
  • tests/codegen/golden/spawns.out is excluded by !**/*.out
  • tests/gen/gen_rules.ml is excluded by !**/gen/**
  • tests/runtime/golden/blocks.out is excluded by !**/*.out
  • tests/runtime/golden/texts.out is excluded by !**/*.out
📒 Files selected for processing (118)
  • docs/ambiguity/proof-obligations.md
  • docs/design/lowering.md
  • docs/design/semantics.md
  • docs/design/symbols.md
  • docs/spec-divergences.md
  • editors/tree-sitter-zane/grammar.js
  • editors/tree-sitter-zane/queries/highlights.scm
  • editors/typst/Zane.sublime-syntax
  • grammar/lexicon.coda
  • grammar/syntax.mly
  • lib/cgt/build.ml
  • lib/cgt/lower.ml
  • lib/cgt/nodes.ml
  • lib/cgt/outcome.ml
  • lib/cgt/program.ml
  • lib/cgt/runtime.ml
  • lib/cgt/state.ml
  • lib/cgt/symbol.ml
  • lib/cgt/to_tree_graph.ml
  • lib/cgt/type_layout.ml
  • lib/cgt/verbs.ml
  • lib/codegen/emit.ml
  • lib/cst/lexer.ml
  • lib/cst/nodes.ml
  • lib/cst/parser.mly
  • lib/cst/to_span_text.ml
  • lib/cst/to_tree_graph.ml
  • lib/sst/lower.ml
  • lib/sst/nodes.ml
  • lib/sst/to_span_text.ml
  • lib/sst/to_tree_graph.ml
  • lib/tst/analyses/exits.ml
  • lib/tst/analyses/guests.ml
  • lib/tst/analyses/moves.ml
  • lib/tst/analyses/read_only.ml
  • lib/tst/analyses/references.ml
  • lib/tst/analyses/scopes.ml
  • lib/tst/analyses/spawns.ml
  • lib/tst/analyses/states.ml
  • lib/tst/check/check.ml
  • lib/tst/check/context.ml
  • lib/tst/check/instances.ml
  • lib/tst/check/overloads.ml
  • lib/tst/dune
  • lib/tst/model/env.ml
  • lib/tst/model/intrinsics.ml
  • lib/tst/model/ty.ml
  • lib/tst/passes/collect.ml
  • lib/tst/passes/type_decls.ml
  • lib/tst/passes/verb_signatures.ml
  • lib/tst/render/to_tree_graph.ml
  • lib/tst/semantics.ml
  • runtime/anchor.c
  • runtime/block.c
  • runtime/dune
  • runtime/list.c
  • runtime/main.c
  • runtime/slot.c
  • runtime/snapshot.c
  • runtime/value.c
  • runtime/zane.h
  • runtime/zane_internal.h
  • tests/codegen/dune.inc
  • tests/codegen/fixtures/arrayrefs/main.zn
  • tests/codegen/fixtures/boxes/main.zn
  • tests/codegen/fixtures/constants/main.zn
  • tests/codegen/fixtures/defaults/main.zn
  • tests/codegen/fixtures/lambdas/main.zn
  • tests/codegen/fixtures/lists/main.zn
  • tests/codegen/fixtures/operators/main.zn
  • tests/codegen/fixtures/owners/main.zn
  • tests/codegen/fixtures/references/main.zn
  • tests/codegen/fixtures/regions/main.zn
  • tests/codegen/fixtures/settled/main.zn
  • tests/codegen/fixtures/spawns/main.zn
  • tests/codegen/fixtures/texts/main.zn
  • tests/codegen/golden/arrayrefs.cgt
  • tests/codegen/golden/arrays.cgt
  • tests/codegen/golden/boxes.cgt
  • tests/codegen/golden/constants.cgt
  • tests/codegen/golden/counting.cgt
  • tests/codegen/golden/defaults.cgt
  • tests/codegen/golden/guests.cgt
  • tests/codegen/golden/hello.cgt
  • tests/codegen/golden/lambdas.cgt
  • tests/codegen/golden/lists.cgt
  • tests/codegen/golden/outcomes.cgt
  • tests/codegen/golden/owners.cgt
  • tests/codegen/golden/references.cgt
  • tests/codegen/golden/settled.cgt
  • tests/codegen/golden/shapes.cgt
  • tests/codegen/golden/spawned.cgt
  • tests/codegen/golden/spawns.cgt
  • tests/codegen/golden/texts.cgt
  • tests/grammar/golden/parser.conflicts.census
  • tests/grammar/golden/stock.conflicts.census
  • tests/parser/golden/main.sst.spans
  • tests/runtime/anchors.c
  • tests/runtime/blocks.c
  • tests/runtime/dune
  • tests/runtime/dune.inc
  • tests/runtime/spawns.c
  • tests/runtime/texts.c
  • tests/semantics/fixtures/typing/accept/app/main.zn
  • tests/semantics/fixtures/typing/reject/bad/conventions.zn
  • tests/semantics/fixtures/typing/reject/bad/marks.zn
  • tests/semantics/fixtures/typing/reject/bad/moves.zn
  • tests/semantics/fixtures/typing/reject/bad/readonly.zn
  • tests/semantics/fixtures/typing/reject/bad/rests.zn
  • tests/semantics/fixtures/typing/reject/bad/scopes.zn
  • tests/semantics/fixtures/typing/reject/bad/sources.zn
  • tests/semantics/fixtures/typing/reject/bad/temporary.zn
  • tests/semantics/fixtures/typing/reject/bad/types.zn
  • tests/semantics/golden/typing.accept.decls
  • tests/semantics/golden/typing.accept.tst
  • tests/semantics/golden/typing.accept.tst.spans
  • tests/semantics/golden/typing.reject.err
  • tests/unit/unit.ml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the new memory model for the Zane language, transitioning from 'guests' and 'hosts' to 'references' and 'owners' (both settled and roaming). This includes representing references as native 64-bit addresses, performing overwrites in-place, and removing the runtime anchor pool. It also adds support for ArrayRef and ArrayRef.fill. The review feedback identifies a compilation error in lib/cgt/lower.ml where Stat.assign is called but is not defined in the codebase, suggesting the use of Stat.Assign instead.

Comment thread lib/cgt/lower.ml
Comment thread lib/cgt/lower.ml

@TheLazyCat00 TheLazyCat00 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would hold this PR until the four P1 findings below are fixed. I reproduced five new-model regressions at 3015da2bf15d46926ec1d791523268ca9103ac96: a function calling-convention mismatch, an overlapping borrow/take in one call, incorrect spawn move classification, an abort that consumes a borrow, and missing result-mode validation after generic instantiation.

The inline comments include the reproductions and observed behavior. Their common prelude is:

package probe;
alias Int = @primitives$Int
alias Unit = @primitives$Unit
alias String = @primitives$String
type Packet = #struct { text String; }
Packet(text String) => init{text;}

I built through TST, CGT and LLVM, and executed the native programs. The function-mode reproduction crashes; the borrow/take and borrowed-abort reproductions lose the caller's text. The existing parser, semantics, codegen, runtime and object-file suites pass. Local validation used OCaml 4.14.1 and LLVM 19.1.1, with a temporary compatibility replacement for the OCaml 5 Filename.temp_dir call in the executable-build helper; no semantic, lowering or runtime code was changed for testing. The OCaml Domain unit suite and Lean proof were not run locally.

I also checked the following problems against base 14e70c53e72ec95ecd653e7d00d2680a155cb1b0. They already exist there, so I am separating them from the new regressions:

  • Abort lowering uses the expression type instead of the declared abort destination. A legal Int?&Packet fail(p &Wrap) { abort p.child; } returns a taken owning record where the handler expects a pointer. Reading e.text crashes on both base and head.
  • Scope checking of abort does not compare the aborted value with the caller's scope. Int?&Packet fail() { p Packet(String("es") + String("caped\n")); abort &p; } is accepted despite returning a reference to a drained local.
  • Handler binder provenance is never populated from the call's abort value/arguments. A legal abort of a holder carrying an &Packet to a caller's inner local can therefore be unpacked by its handler into an outer &Packet binding. The checker accepts the escaping reference, and the dynamic-string reproduction prints nothing after the inner scope drains. This also occurs on base.

Those inherited gaps still need attention for the stated abort/lifetime guarantees. The new non-escaping borrow semantics make the fourth inline finding a new caller-visible regression even though the missing abort-store dispatch itself is older.

The existing review's claim that Stat.assign is undefined is a false positive: it is defined in lib/cgt/nodes.ml, and the compiler builds.

Comment thread lib/tst/model/ty.ml
Comment thread lib/tst/analyses/moves.ml Outdated
Comment thread lib/tst/analyses/spawns.ml Outdated
Comment thread lib/tst/analyses/moves.ml Outdated
Comment thread lib/tst/passes/type_decls.ml
- A function argument matches a parameter only at the passing modes it was
  written with, once inference fills the parameter: `Int[Packet]` no longer
  fills `Int[^T]` with a reference type, nor `Int[Int]` an `Int[&T]`.
- An argument lent to a borrow stays lent for the whole call, so a later
  argument may not take the same place.
- Spawn safety reads the new modes: a `^T` argument or a `^T` local's
  initializer moves the owner, and a bare reference-type argument borrows it.
- An abort is a store, like a return: the move, reference-source and scope
  checks see it at the declared abort type, lowering hands it on at that type,
  and a handler's binder names what the call's arguments name.
- A bare type parameter as a result or abort type is rejected once an instance
  fills it with a reference type, including inside function types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ArFxFkp985vTC6aHAAxp82
@TheLazyCat00

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the memory model by replacing 'guests' and 'hosts' with 'references' (&T) and 'roaming owners' (^T). This change involves parser updates to support the caret (^) marker, AST modifications, and a major rewrite of the static analysis passes (introducing references.ml, states.ml, and scopes.ml). The C runtime is also simplified by removing anchors and backpointers, and implementing in-place overwrites. The review identified several critical omissions where the newly introduced Ty.Roaming type variant is not handled, specifically in scopes.ml's place function (which fails to check declared block scopes, allowing dangling references), verb_signatures.ml's home function, and type_decls.ml's concept_in and is_reference functions.

Comment thread lib/tst/analyses/scopes.ml
Comment thread lib/tst/passes/verb_signatures.ml Outdated
Comment thread lib/tst/passes/type_decls.ml Outdated
Comment thread lib/tst/passes/type_decls.ml
@TheLazyCat00

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1558f40819

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/tst/passes/type_decls.ml Outdated
Comment thread lib/tst/passes/verb_signatures.ml Outdated
Comment thread lib/tst/passes/verb_signatures.ml
@TheLazyCat00
TheLazyCat00 merged commit fbf0760 into main Oct 5, 2026
8 of 11 checks passed
@TheLazyCat00
TheLazyCat00 deleted the claude/loving-pascal-0m6cxi branch October 5, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants