feat(obs): bind case Some(&mut v) as a mutable reference

A Store-context capture becomes RefKind=2 (writable); `&v` stays read-only. Both still register a borrow, so the owner cannot be del-ed inside the arm.
This commit is contained in:
TermiNexus committed 2026-11-04 17:07:21 +08:00
1 parent 40691567f5
commit 2e5218abc6
1 file changed
+6 -2
+6 -2
View File
@@ -410,7 +410,9 @@ novirtual class MatchGenMixin:
self.Gen.VarGen.define_var(trans.SymTab, ma_s.name, slot)
self.Gen.VarGen.set_var_life(trans.SymTab, ma_s.name, GenTypes.LIFE_FRAME)
elif sub is not None and sub.kind() == ast.ASTKind.UnaryOp:
# `Some(&v)`: bind the payload by reference (a borrow, not an owner).
# `Some(&v)` / `Some(&mut v)`: bind the payload by reference (a borrow).
if trans.StrictOBS == 0:
self.Gen.TypeGenErr.fatal_error(sub, "reference patterns (`&v` / `&mut v`) require `from __future__ import __obs__`", "TypeError")
uo_s: ast.UnaryOp* = ast.UnaryOp*(sub)
if uo_s.op == ast.OpKind.AddrOf and uo_s.operand is not None \
and uo_s.operand.kind() == ast.ASTKind.Name:
@@ -421,7 +423,9 @@ novirtual class MatchGenMixin:
mlirlite.build_store(builder, subject_val, slot2)
self.Gen.VarGen.define_var(trans.SymTab, nm_s.id, slot2)
self.Gen.VarGen.set_var_life(trans.SymTab, nm_s.id, GenTypes.LIFE_FRAME)
self.Gen.VarGen.set_var_ref_kind(trans.SymTab, nm_s.id, 1)
# `&mut v` uses Store context: a mutable reference.
ref_kind_pat: int = 2 if nm_s.ctx == ast.ASTCtx.Store else 1
self.Gen.VarGen.set_var_ref_kind(trans.SymTab, nm_s.id, ref_kind_pat)
own_r: str = self._borrow_owner_name(node.subject)
if own_r is not None:
self.Gen.StmtGen._BorrowAdd(trans, own_r, nm_s.id)