iter remove-mut-var-assign.1: atomic removal of mut/var/assign
mut/var/assign removed from AILang entirely and atomically. Deleted: Term::Mut/Term::Assign/struct MutVar; the three Form-A keywords + parse_mut/parse_assign + grammar EBNF; the 4 mut CheckError variants; the mut_scope_stack synth threading (param dropped from synth + every internal/external/test caller); the two lower_term arms; and every exhaustive no-_ Term::Mut/Term::Assign match arm across 17 source files — cut in lockstep with DESIGN.md, fixtures, the drift trio, carve-out and roadmap so the schema is honest at every commit. No catch-all wildcard introduced (verified). loop/recur + let/if are the surviving forms. The shared codegen alloca machinery survives (loop reuses it): mut_var_allocas renamed binder_allocas (representation-only, loop codegen byte-identical) and the shared Term::Lam escape guard simplified to !loop_stack.is_empty() with the loop half (LoopBinderCapturedByLambda) byte-equivalent. Feature-acceptance applied inverted: the removed feature fails clause 2 (redundant) and clause 3 (IS the iterated-mutable-state bug class). Behaviour preservation is executable: mut_counter/mut_sum_floats still print 55 after the faithful let/if rewrite. The removal is made executable by the new mut_removed_pin.rs (4 must-fail pins). Independent verification: cargo test --workspace 605/0, zero residual mut symbols in any crate source, loop/recur non-regression all green (55 / 500000500000 / infinite-compiles / the lambda_capturing_loop_binder pin), roundtrip_cli PASS. One DONE_WITH_CONCERNS: a 4th recurrence of the recon-undercount class (in-source mod tests + a drift-pin fn + 5 orphaned mut .ail.json carve-outs + a non-enumerated E0599); all resolved within implementer remit, no behaviour change. Milestone-close audit then fieldtest remain. spec docs/specs/2026-05-18-remove-mut-var-assign.md (grounding PASS) plan docs/plans/remove-mut-var-assign.1.md
This commit is contained in:
@@ -1,17 +1,4 @@
|
||||
; Fieldtest mut-local #1 — factorial 5! via straight-line mut updates.
|
||||
;
|
||||
; Task: print 5! (= 120) using a `mut` block that names a running
|
||||
; product and unrolls five multiplications as straight-line statements.
|
||||
; This is the most direct possible use of mut-local: no helper fn, no
|
||||
; iteration, just a sequence of in-block updates terminated by reading
|
||||
; the var. The LLM-author's mental model of "I want a local accumulator"
|
||||
; maps 1:1 onto the surface here.
|
||||
;
|
||||
; Why this fits mut-local's scope: the milestone supplies only sealed
|
||||
; lexically-scoped mutables, with no `while` or `for`. Straight-line
|
||||
; unroll is the *only* shape inside one mut block that needs no helper.
|
||||
;
|
||||
; Expected stdout: 120
|
||||
; Print 5! (= 120) via a let-threaded running product.
|
||||
|
||||
(module mut-local_1_factorial
|
||||
|
||||
@@ -19,12 +6,4 @@
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
(mut
|
||||
(var prod (con Int) 1)
|
||||
(assign prod (app * prod 1))
|
||||
(assign prod (app * prod 2))
|
||||
(assign prod (app * prod 3))
|
||||
(assign prod (app * prod 4))
|
||||
(assign prod (app * prod 5))
|
||||
prod)))))
|
||||
(app print (let prod 1 (let prod (app * prod 1) (let prod (app * prod 2) (let prod (app * prod 3) (let prod (app * prod 4) (let prod (app * prod 5) prod))))))))))
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
; Fieldtest mut-local #2 — classify a temperature into a band using
|
||||
; nested if-branches that each update a mut-Int "category code".
|
||||
;
|
||||
; Task: given a temperature value, set a category-code mut-var to
|
||||
; 0 (freezing), 1 (cold), 2 (warm), 3 (hot) by walking through a
|
||||
; cascade of if-branches. Print the resulting code.
|
||||
;
|
||||
; Why this fits mut-local's scope: this exercises mut composed with
|
||||
; `if` — each branch contains a single `(assign ...)`. The seal-by-
|
||||
; construction promise says the if-branch can write to the var, and
|
||||
; the var's value flows out of the branch as the latest store. This is
|
||||
; a use of mut that *replaces* what a chain of let-rebinds would
|
||||
; otherwise do, and a chain of let-rebinds is the AILang author's
|
||||
; usual workaround for "set this variable conditionally" — so the
|
||||
; mut form should be measurably cleaner here.
|
||||
;
|
||||
; Expected stdout: 2 (room temperature 22 = "warm")
|
||||
; Classify a temperature into a 0..3 band via a let-bound code.
|
||||
; classify 22 = 2 ("warm"). Expected stdout: 2
|
||||
|
||||
(module mut-local_2_classify_temp
|
||||
|
||||
@@ -22,17 +7,7 @@
|
||||
(doc "Return category code 0..3 for temperature t in degrees C.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(params t)
|
||||
(body
|
||||
(mut
|
||||
(var code (con Int) 0)
|
||||
(if (app < t 0)
|
||||
(assign code 0)
|
||||
(if (app < t 15)
|
||||
(assign code 1)
|
||||
(if (app < t 28)
|
||||
(assign code 2)
|
||||
(assign code 3))))
|
||||
code)))
|
||||
(body (let code 0 (let code (if (app < t 0) 0 (if (app < t 15) 1 (if (app < t 28) 2 3))) code))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
; Fieldtest mut-local #3 — evaluate the polynomial
|
||||
; p(x) = 2 x^3 - 3 x^2 + 5 x - 7
|
||||
; at x = 2.5 by Horner's method, using a Float mut-var as the running
|
||||
; accumulator and unrolling the four Horner steps as straight-line
|
||||
; assigns.
|
||||
;
|
||||
; Why this fits mut-local's scope: the accumulator is a Float, the
|
||||
; updates are straight-line (no iteration), and the mut form removes
|
||||
; the four nested let-rebinds an LLM-author would otherwise write
|
||||
; ("p1 = ..., p2 = p1*x + ..., p3 = p2*x + ...") — each rebind needing
|
||||
; a fresh name. Reusing one name for the running accumulator is the
|
||||
; natural shape, and mut supplies it.
|
||||
;
|
||||
; Hand-check (Horner): start with leading coeff 2.0, then for each
|
||||
; lower coefficient do acc = acc * x + c:
|
||||
; 2.0 * 2.5 + (-3) = 5.0 - 3 = 2.0
|
||||
; 2.0 * 2.5 + 5 = 5.0 + 5 = 10.0
|
||||
; 10.0 * 2.5 + (-7) = 25.0 - 7 = 18.0
|
||||
; Expected stdout: 18 (Float 18.0 via %g; print drops the trailing
|
||||
; ".0" the same way it does for the Float fixture mut_sum_floats.ail.)
|
||||
; Evaluate p(x) = 2x^3 - 3x^2 + 5x - 7 at x = 2.5 by Horner's method
|
||||
; via a let-threaded Float accumulator. Expected stdout: 18
|
||||
|
||||
(module mut-local_3_horner
|
||||
|
||||
@@ -25,10 +7,4 @@
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
(mut
|
||||
(var acc (con Float) 2.0)
|
||||
(assign acc (app - (app * acc 2.5) 3.0))
|
||||
(assign acc (app + (app * acc 2.5) 5.0))
|
||||
(assign acc (app - (app * acc 2.5) 7.0))
|
||||
acc)))))
|
||||
(app print (let acc 2.0 (let acc (app - (app * acc 2.5) 3.0) (let acc (app + (app * acc 2.5) 5.0) (let acc (app - (app * acc 2.5) 7.0) acc))))))))
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
; Fieldtest mut-local #4 — Bool mut-var "found-a-factor" flag.
|
||||
;
|
||||
; Task: probe whether n has a small prime factor (2, 3, 5, or 7) by
|
||||
; running four straight-line checks; if any check matches, set a Bool
|
||||
; mut-var to true. Print the flag at the end.
|
||||
;
|
||||
; The straight-line form here is the natural shape: an LLM-author asked
|
||||
; to "test these four conditions and OR the results" would otherwise
|
||||
; write a chain of `||` operators (no such operator in AILang surface)
|
||||
; or a nested chain of `(if ... (if ... ))`. The mut form replaces both
|
||||
; with a flat sequence whose intent ("set this flag if any of these
|
||||
; matches") reads top-to-bottom.
|
||||
;
|
||||
; Test against n = 91 = 7 * 13 — only the divisible-by-7 check fires.
|
||||
; Probe whether n has a small prime factor (2, 3, 5, 7) via a
|
||||
; let-threaded Bool flag. has_small_factor 91 = true (91 = 7 * 13).
|
||||
; Expected stdout: true
|
||||
|
||||
(module mut-local_4_has_small_factor
|
||||
@@ -19,14 +7,7 @@
|
||||
(fn has_small_factor
|
||||
(type (fn-type (params (con Int)) (ret (con Bool))))
|
||||
(params n)
|
||||
(body
|
||||
(mut
|
||||
(var found (con Bool) false)
|
||||
(if (app == (app % n 2) 0) (assign found true) (lit-unit))
|
||||
(if (app == (app % n 3) 0) (assign found true) (lit-unit))
|
||||
(if (app == (app % n 5) 0) (assign found true) (lit-unit))
|
||||
(if (app == (app % n 7) 0) (assign found true) (lit-unit))
|
||||
found)))
|
||||
(body (let found false (let found (if (app == (app % n 2) 0) true found) (let found (if (app == (app % n 3) 0) true found) (let found (if (app == (app % n 5) 0) true found) (let found (if (app == (app % n 7) 0) true found) found)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
; Fieldtest mut-local #5 — deliberate probe of the seal-by-construction
|
||||
; promise: try to lift a mut-var into a lambda closure.
|
||||
;
|
||||
; Spec §"Out of scope": "Lambda capture of a mut-var. A lambda body
|
||||
; whose free vars include a mut-var of an enclosing Term::Mut is
|
||||
; rejected at typecheck with CheckError::MutVarCapturedByLambda."
|
||||
;
|
||||
; This file is EXPECTED TO FAIL at `ail check` with the
|
||||
; `mut-var-captured-by-lambda` diagnostic. The purpose is to probe:
|
||||
; - that the diagnostic actually fires
|
||||
; - that its rendered text is actionable
|
||||
; - that it points at the lambda site, not somewhere else
|
||||
;
|
||||
; The shape: a mut block declares `count`, builds a closure that would
|
||||
; close over `count`, and tries to return the closure. An LLM-author
|
||||
; might write this naïvely thinking "I just need a small callback that
|
||||
; updates the running count" — exactly the shape the seal forbids.
|
||||
|
||||
(module mut-local_5_lambda_capture_probe
|
||||
|
||||
(fn make_bumper
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int))
|
||||
(ret (fn-type (params (con Int)) (ret (con Int))))))
|
||||
(params seed)
|
||||
(body
|
||||
(mut
|
||||
(var count (con Int) 0)
|
||||
(assign count seed)
|
||||
(lam (params (typed n (con Int)))
|
||||
(ret (con Int))
|
||||
(body (app + n count))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app (app make_bumper 10) 5)))))
|
||||
@@ -1,18 +0,0 @@
|
||||
; Fieldtest mut-local #6 — deliberate diagnostic probe. EXPECTED TO
|
||||
; FAIL at `ail check`.
|
||||
;
|
||||
; Probes `mut-var-unsupported-type` — declaring a Str mut-var.
|
||||
; (A sibling fixture used to probe `assign-type-mismatch` by assigning
|
||||
; 1.5 to an Int var; on the same surface the diagnostic also fires
|
||||
; with the same double-bracket-prefix shape.)
|
||||
|
||||
(module mut-local_6_diag_probe
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
(mut
|
||||
(var s (con Str) "hello")
|
||||
s)))))
|
||||
+12
-37
@@ -1,62 +1,37 @@
|
||||
(module mut
|
||||
|
||||
(fn mut_empty
|
||||
(doc "Iter mut.1 — empty mut block; body is a single Int literal.")
|
||||
(doc "Empty block; body is a single Int literal.")
|
||||
(type (fn-type (params) (ret (con Int))))
|
||||
(params)
|
||||
(body (mut 0)))
|
||||
(body 0))
|
||||
|
||||
(fn mut_single_var
|
||||
(doc "Iter mut.1 — one var, one assign, final expression reads the var.")
|
||||
(doc "let-rebind: x starts at 0, the block value is x + 1.")
|
||||
(type (fn-type (params) (ret (con Int))))
|
||||
(params)
|
||||
(body
|
||||
(mut
|
||||
(var x (con Int) 0)
|
||||
(assign x (app + x 1))
|
||||
x)))
|
||||
(body (let x 0 (let x (app + x 1) x))))
|
||||
|
||||
(fn mut_two_vars
|
||||
(doc "Iter mut.1 — two vars, two assigns, final expression combines them.")
|
||||
(doc "Two let-threaded scalars combined into the block value.")
|
||||
(type (fn-type (params) (ret (con Float))))
|
||||
(params)
|
||||
(body
|
||||
(mut
|
||||
(var sum (con Float) 0.0)
|
||||
(var count (con Int) 0)
|
||||
(assign sum (app + sum 1.0))
|
||||
(assign count (app + count 1))
|
||||
(app + sum (app int_to_float count)))))
|
||||
(body (let sum 0.0 (let count 0 (let sum (app + sum 1.0) (let count (app + count 1) (app + sum (app int_to_float count))))))))
|
||||
|
||||
(fn mut_nested_shadow
|
||||
(doc "Iter mut.1 — outer var shadowed by inner mut block's var of the same name.")
|
||||
(doc "Nested let shadowing; inner binding is the block value.")
|
||||
(type (fn-type (params) (ret (con Int))))
|
||||
(params)
|
||||
(body
|
||||
(mut
|
||||
(var x (con Int) 10)
|
||||
(assign x (app + x 1))
|
||||
(mut
|
||||
(var x (con Int) 100)
|
||||
(assign x (app + x 1))
|
||||
x))))
|
||||
(body (let x 10 (let x (app + x 1) (let x 100 (let x (app + x 1) x))))))
|
||||
|
||||
(fn mut_returns_bool
|
||||
(doc "Iter mut.1 — exercise Bool as a supported scalar var type.")
|
||||
(doc "Bool scalar threaded through let; block value is the latest binding.")
|
||||
(type (fn-type (params) (ret (con Bool))))
|
||||
(params)
|
||||
(body
|
||||
(mut
|
||||
(var flag (con Bool) false)
|
||||
(assign flag true)
|
||||
flag)))
|
||||
(body (let flag false (let flag true flag))))
|
||||
|
||||
(fn mut_returns_unit
|
||||
(doc "Iter mut.1 — exercise Unit as the supported scalar zero case.")
|
||||
(doc "Unit scalar threaded through let; block value is the latest binding.")
|
||||
(type (fn-type (params) (ret (con Unit))))
|
||||
(params)
|
||||
(body
|
||||
(mut
|
||||
(var u (con Unit) (lit-unit))
|
||||
(assign u (lit-unit))
|
||||
u))))
|
||||
(body (let u (lit-unit) (let u (lit-unit) u)))))
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
(module mut_counter
|
||||
|
||||
(fn main
|
||||
(doc "Iter mut.3 — sum 1..10 via mut + recursive helper. Expected stdout: 55.")
|
||||
(doc "Sum 1..10 via a tail-recursive helper. Expected stdout: 55.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
(mut
|
||||
(var sum (con Int) 0)
|
||||
(assign sum (app sum_helper 1 10 0))
|
||||
sum))))
|
||||
(app print (app sum_helper 1 10 0))))
|
||||
|
||||
(fn sum_helper
|
||||
(doc "Accumulator-style tail-recursive helper — sum from lo through hi inclusive.")
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
(module mut_sum_floats
|
||||
|
||||
(fn main
|
||||
(doc "Iter mut.3 — Float twin of mut_counter. Expected stdout: 55 (Float-55.0 via %g).")
|
||||
(doc "Float twin of mut_counter via a tail-recursive helper. Expected stdout: 55 (Float-55.0 via %g).")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
(mut
|
||||
(var sum (con Float) 0.0)
|
||||
(assign sum (app sum_helper 1.0 10.0 0.0))
|
||||
sum))))
|
||||
(app print (app sum_helper 1.0 10.0 0.0))))
|
||||
|
||||
(fn sum_helper
|
||||
(doc "Accumulator-style tail-recursive Float helper — sum from lo through hi inclusive.")
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_assign_out_of_scope",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.2: assigning to a name not declared as a mut-var fires mut-assign-out-of-scope.",
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"init": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "assign",
|
||||
"name": "y",
|
||||
"value": { "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
},
|
||||
"rhs": { "t": "var", "name": "x" }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_assign_outside_mut",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.2: Term::Assign with no enclosing Term::Mut ancestor fires mut-assign-out-of-scope.",
|
||||
"body": {
|
||||
"t": "assign",
|
||||
"name": "x",
|
||||
"value": { "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_assign_type_mismatch",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.2: assigning Float to Int mut-var fires assign-type-mismatch.",
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"init": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "assign",
|
||||
"name": "x",
|
||||
"value": { "t": "lit", "lit": { "kind": "float", "bits": "3ff8000000000000" } }
|
||||
},
|
||||
"rhs": { "t": "var", "name": "x" }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_nested_shadow_legal",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Float" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.2: nested mut block with inner var shadowing outer; inner Float wins. Typechecks clean.",
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"init": { "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": { "k": "con", "name": "Float" },
|
||||
"init": { "t": "lit", "lit": { "kind": "float", "bits": "4000000000000000" } }
|
||||
}
|
||||
],
|
||||
"body": { "t": "var", "name": "x" }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_var_captured_by_lambda",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.4-tidy: a lambda inside a mut block that references the enclosing mut-var `x` is rejected with mut-var-captured-by-lambda. Mut-vars are alloca-resident and lexically scoped; lifting them into a heap-closure env is deferred to a follow-on milestone (ref-types + !Mut effect).",
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"init": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "f",
|
||||
"value": {
|
||||
"t": "lam",
|
||||
"params": [],
|
||||
"paramTypes": [],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"effects": [],
|
||||
"body": { "t": "var", "name": "x" }
|
||||
},
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "test_mut_var_unsupported_type",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Str" },
|
||||
"effects": []
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter mut.2: a Str-typed mut-var fires mut-var-unsupported-type (heap-RC-managed types deferred).",
|
||||
"body": {
|
||||
"t": "mut",
|
||||
"vars": [
|
||||
{
|
||||
"name": "s",
|
||||
"type": { "k": "con", "name": "Str" },
|
||||
"init": { "t": "lit", "lit": { "kind": "str", "value": "hello" } }
|
||||
}
|
||||
],
|
||||
"body": { "t": "var", "name": "s" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user