From 023233895cac69b2622f05a94ac076123e54b7bc Mon Sep 17 00:00:00 2001 From: "shoney.arickathil" Date: Tue, 18 Aug 2026 19:10:39 +0200 Subject: [PATCH] test(compiler): unit helpers run inference; retarget borrow-escape fixture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire Gcinfer.infer into runner.ml's owner_str/emit_str so the unit tests classify GC-ness identically to the driver (prerequisite for removing @gc: its tests read the golden .wo through the library). That exposed owner-err/borrow-escape.wo, which tested WO-E304 on *class* escapes — now legally demand-promoted. Retargeted it to CONTAINER (`multi Text`) escapes, which are owned and never promoted, so it still exercises the three WO-E304 shapes (stored-in-field, returned, moved-to-take). Assertion positions + golden re-blessed. Verified: woc-test 566/0, test_diag 14/0, oop-e2e 79/0. Co-Authored-By: Claude Opus 5 (1M context) --- .../golden/owner-err/borrow-escape.expected | 18 +++++++-------- .../test/golden/owner-err/borrow-escape.wo | 22 +++++++++---------- compiler/test/runner.ml | 7 ++++-- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/compiler/test/golden/owner-err/borrow-escape.expected b/compiler/test/golden/owner-err/borrow-escape.expected index b45cf7f..180edd2 100644 --- a/compiler/test/golden/owner-err/borrow-escape.expected +++ b/compiler/test/golden/owner-err/borrow-escape.expected @@ -1,19 +1,19 @@ -owner-err/borrow-escape.wo:9:16: error WO-E304: borrow of `other` cannot be stored in `self.box` — borrows cannot outlive their scope - self.box = other - ^ +owner-err/borrow-escape.wo:9:18: error WO-E304: borrow of `other` cannot be stored in `self.items` — borrows cannot outlive their scope + self.items = other + ^ owner-err/borrow-escape.wo:8:12: `other` is borrowed here — declare it `take other: T` to pass ownership in - fn adopt(other: Box) { + fn adopt(other: multi Text) { ^ -owner-err/borrow-escape.wo:18:10: error WO-E304: borrow of `h.box` escapes `leak` — borrows cannot outlive their scope - return h.box +owner-err/borrow-escape.wo:18:10: error WO-E304: borrow of `h.items` escapes `leak` — borrows cannot outlive their scope + return h.items ^ owner-err/borrow-escape.wo:17:9: `h` is borrowed here — declare it `take h: T` to pass ownership in - fn leak(h: Holder) -> Box { + fn leak(h: Holder) -> multi Text { ^ -owner-err/borrow-escape.wo:22:15: error WO-E304: borrow of `h.box` cannot be passed to `take b` — borrows cannot outlive their scope - return keep(h.box) +owner-err/borrow-escape.wo:22:15: error WO-E304: borrow of `h.items` cannot be passed to `take b` — borrows cannot outlive their scope + return keep(h.items) ^ owner-err/borrow-escape.wo:21:10: `h` is borrowed here — declare it `take h: T` to pass ownership in fn stash(h: Holder) -> Int { diff --git a/compiler/test/golden/owner-err/borrow-escape.wo b/compiler/test/golden/owner-err/borrow-escape.wo index 336b252..9ae3294 100644 --- a/compiler/test/golden/owner-err/borrow-escape.wo +++ b/compiler/test/golden/owner-err/borrow-escape.wo @@ -1,23 +1,23 @@ -class Box { - n: Int -} - +-- Iteration 7b: WO-E304 borrow escapes, using CONTAINER values (`multi Text`). +-- A class value that escapes is demand-promoted to traced, so the illustrative +-- escapes must be containers, which are owned and never promoted. Mirrors the +-- run/borrow-escape-return corpus case (a class escape, now legal). class Holder { - box: Box + items: multi Text - fn adopt(other: Box) { - self.box = other + fn adopt(other: multi Text) { + self.items = other } } -fn keep(take b: Box) -> Int { +fn keep(take b: multi Text) -> Int { return 0 } -fn leak(h: Holder) -> Box { - return h.box +fn leak(h: Holder) -> multi Text { + return h.items } fn stash(h: Holder) -> Int { - return keep(h.box) + return keep(h.items) } diff --git a/compiler/test/runner.ml b/compiler/test/runner.ml index 8d644a5..0a1a971 100644 --- a/compiler/test/runner.ml +++ b/compiler/test/runner.ml @@ -39,6 +39,7 @@ module Parser = Woc_lib.Parser module Dump = Woc_lib.Dump module Types = Woc_lib.Types module Owner = Woc_lib.Owner +module Gcinfer = Woc_lib.Gcinfer module Emit = Woc_lib.Emit module Disasm = Woc_lib.Disasm @@ -1807,6 +1808,7 @@ let owner_str ~file src = let toks = Lexer.tokenize collector ~file src in let prog = Parser.parse collector ~file toks in let syms, () = Types.typecheck ~file prog collector in + let syms = Gcinfer.infer [ (file, prog) ] syms in let tables = Owner.analyze ~file prog syms collector in (tables, collector) @@ -1819,6 +1821,7 @@ let emit_str ~file src = let toks = Lexer.tokenize collector ~file src in let prog = Parser.parse collector ~file toks in let syms, () = Types.typecheck ~file prog collector in + let syms = Gcinfer.infer [ (file, prog) ] syms in let tables = Owner.analyze ~file prog syms collector in (* Single-file helper (every golden fixture is one file): its own module is "." and that module's own symbols are exactly `syms` — @@ -1929,7 +1932,7 @@ let () = field, returned, moved out to a `take` parameter. *) match owner_err_fixture "borrow-escape" with | [ store; ret; take ] -> - check_site "borrow-escape (stored in a field)" ~code:"WO-E304" ~line:9 ~col:16 ~rel_line:8 + check_site "borrow-escape (stored in a field)" ~code:"WO-E304" ~line:9 ~col:18 ~rel_line:8 ~rel_col:12 store; check_site "borrow-escape (returned)" ~code:"WO-E304" ~line:18 ~col:10 ~rel_line:17 ~rel_col:9 ret; @@ -1937,7 +1940,7 @@ let () = ~rel_line:21 ~rel_col:10 take; (* spec section 6's own wording for this diagnostic *) check "borrow-escape: names the place and the function it escapes" - (Option.is_some (find_substring ~needle:"borrow of `h.box` escapes `leak`" ret.Diag.message)) + (Option.is_some (find_substring ~needle:"borrow of `h.items` escapes `leak`" ret.Diag.message)) | ds -> check_eq "borrow-escape: exactly three ownership errors" ~expected:3 ~actual:(List.length ds) string_of_int