From 2e5218abc6169790821a9004f1e962f6cc417398 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 4 Nov 2026 16:26:49 +0800 Subject: [PATCH] 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. --- App/lib/core/Gen/MatchGenMixin.vp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/MatchGenMixin.vp b/App/lib/core/Gen/MatchGenMixin.vp index 3ab52b3..561b337 100644 --- a/App/lib/core/Gen/MatchGenMixin.vp +++ b/App/lib/core/Gen/MatchGenMixin.vp @@ -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)