test(compiler): unit helpers run inference; retarget borrow-escape fixture
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) <noreply@anthropic.com>
This commit is contained in:
parent
07bcc1c485
commit
1cedbda0bb
3 changed files with 25 additions and 22 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue