74379b29e5
Schema floor for explicit reuse hints. Adds Term::ReuseAs
{ source: Box<Term>, body: Box<Term> } with serde tag "reuse-as",
form-A (reuse-as <source> <body>). Schema choice (wrapper, not
modifier-on-Ctor) and rationale recorded in DESIGN.md.
Codegen is identity under all --alloc strategies — lower body,
drop source on the floor. Iter 18d.2 will lower this as the
in-place rewrite under --alloc=rc.
User-facing diagnostics:
- typecheck reuse-as-non-allocating-body: body must be a
Term::Ctor or Term::Lam, the two AST shapes that allocate.
Other shapes (literal, var, app, ...) emit this with a
suggested_rewrite that drops the wrapper.
- linearity reuse-as-source-not-bare-var: source must be a
Term::Var referring to an in-scope binder. Anything else
(literal, nested expression) is rejected here. Suggested
rewrite drops the wrapper.
- linearity use-after-consume at a reuse-as site: source must
not have been consumed earlier in the body. Suggested rewrite
drops the wrapper.
- Visiting reuse-as marks source consumed for the rest of the
body, so a subsequent use of the same binder flags
use-after-consume against it.
Uniqueness inference treats source as Consume — the consume
shows up in the side table for the codegen consumer.
Tests:
- 4 surface parse-tests (round-trip, no-args, one-arg, full
parse_term/term_to_form_a round-trip).
- 1 typecheck unit test (non-allocating body).
- 2 linearity unit tests (non-var source, after-consume).
- 1 integration test (happy-path map_inc in all-explicit mode
is linearity-clean).
- 1 E2E test running the canonical map_inc-via-reuse-as fixture
under --alloc=gc, asserting stdout 9.
- New fixture examples/reuse_as_demo.{ailx,ail.json}.
Test deltas: E2E 55 -> 56, ailang-check unit 43 -> 46,
ailang-check workspace 8 -> 9, surface 14 -> 18. cargo test
--workspace green. No existing fixture's canonical JSON changed.
1 line
2.5 KiB
JSON
1 line
2.5 KiB
JSON
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"List"}],"name":"Cons"}],"doc":"Monomorphic singly-linked Int list — boxed, recursive.","kind":"type","name":"List"},{"body":{"arms":[{"body":{"args":[],"ctor":"Nil","t":"ctor","type":"List"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"body":{"args":[{"args":[{"name":"h","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"map_inc","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"List"},"source":{"name":"xs","t":"var"},"t":"reuse-as"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Increment each Int in xs. The Cons arm uses (reuse-as xs ...) — author asserts that the freshly-allocated Cons cell should reuse xs's slot. In 18d.1 codegen treats this as identity.","kind":"fn","name":"map_inc","params":["xs"],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"List"}],"ret":{"k":"con","name":"List"},"ret_mode":"own"}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"h","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Consume xs, sum its elements.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"List"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"args":[{"args":[{"args":[{"name":"xs","t":"var"}],"fn":{"name":"map_inc","t":"var"},"t":"app"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"name":"xs","t":"let","value":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}},"doc":"Build [1,2,3]; map_inc → [2,3,4]; sum_list → 9. Print 9.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"reuse_as_demo","schema":"ailang/v0"} |