writeonce/tests/corpus/gc/budget-steps/fixture.wo
shoney.arickathil 3f842f854b feat(compiler): remove @gc from the language — GC-ness is fully inferred (7b)
`@gc` is no longer part of the language: a developer never writes or mentions
it. GC-ness is decided entirely by inference (structural cycles + demand
promotion), which the earlier 7b commits made complete and precise.

- parser: `@gc` on a class is now WO-E104 ("GC-ness is inferred; run
  `woc --dump-gc`. Remove it."). `is_gc` stays false; the class classifies by
  inference. No `.wo` in the repo carries `@gc` anymore.
- types.ml: retired the WO-W201 machinery (suggest_gc_annotation,
  has_recursive_structure(_type), has_unique_field, gc_suggestion_code) — it
  suggested `@gc`, now obsolete since inference traces exactly those classes.
- runner.ml: deleted the 8 WO-W201 gc-suggestion test blocks; the @gc-exemption
  test's `Cache` is made self-referential so inference classifies it gc without
  an annotation.
- fixtures: dropped `@gc` from rc.wo (Cache demand-promotes via its escape),
  elision.wo (Cache given a self-ref to stay structurally gc for the rc-elision
  dump), pricing-demo.wo (PriceCache doesn't escape -> now owned), and the
  abandoned-cycle/budget-steps corpus (Node is structurally gc). rc.wo keeps a
  placeholder comment line so its line-indexed rc assertions hold. Goldens
  re-blessed.
- docs: error catalog gains WO-E104 and marks WO-W201 retired; gc-cycle README
  records the keyword removal.

Verified: woc-test 553/0 (was 566 minus the 13 retired WO-W201 checks),
test_diag 14/0, oop-e2e 79/0, employee 8/0, log-watcher 7/0. `git grep '@gc'`
finds only comments — success criterion 1 met.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 19:19:09 +02:00

156 lines
6.6 KiB
Text

-- 129 padding Int fields (p1..p129) push Node's instance size past the
-- arena's 1024-byte size-class ceiling (runtime/src/obj.h), so instances
-- allocate through plain malloc/free instead of the bump arena -- the
-- same trick runtime/test/test_cycle.c uses (BIG=130) so ASan can prove
-- a Node is actually freed, not just recycled inside the arena's own
-- freelist where a sanitizer can never see it.
class Node {
peers: multi Node
p1: Int
p2: Int
p3: Int
p4: Int
p5: Int
p6: Int
p7: Int
p8: Int
p9: Int
p10: Int
p11: Int
p12: Int
p13: Int
p14: Int
p15: Int
p16: Int
p17: Int
p18: Int
p19: Int
p20: Int
p21: Int
p22: Int
p23: Int
p24: Int
p25: Int
p26: Int
p27: Int
p28: Int
p29: Int
p30: Int
p31: Int
p32: Int
p33: Int
p34: Int
p35: Int
p36: Int
p37: Int
p38: Int
p39: Int
p40: Int
p41: Int
p42: Int
p43: Int
p44: Int
p45: Int
p46: Int
p47: Int
p48: Int
p49: Int
p50: Int
p51: Int
p52: Int
p53: Int
p54: Int
p55: Int
p56: Int
p57: Int
p58: Int
p59: Int
p60: Int
p61: Int
p62: Int
p63: Int
p64: Int
p65: Int
p66: Int
p67: Int
p68: Int
p69: Int
p70: Int
p71: Int
p72: Int
p73: Int
p74: Int
p75: Int
p76: Int
p77: Int
p78: Int
p79: Int
p80: Int
p81: Int
p82: Int
p83: Int
p84: Int
p85: Int
p86: Int
p87: Int
p88: Int
p89: Int
p90: Int
p91: Int
p92: Int
p93: Int
p94: Int
p95: Int
p96: Int
p97: Int
p98: Int
p99: Int
p100: Int
p101: Int
p102: Int
p103: Int
p104: Int
p105: Int
p106: Int
p107: Int
p108: Int
p109: Int
p110: Int
p111: Int
p112: Int
p113: Int
p114: Int
p115: Int
p116: Int
p117: Int
p118: Int
p119: Int
p120: Int
p121: Int
p122: Int
p123: Int
p124: Int
p125: Int
p126: Int
p127: Int
p128: Int
p129: Int
}
-- Two INDEPENDENT 2-cycles (a<->b, c<->d), both abandoned. With
-- WO_GC_BUDGET=2 (fixture.gc_budget) each step's whole-component budget
-- covers exactly one 2-node cycle (test_budget_one_cycle_per_step in
-- runtime/test/test_cycle.c proves this at the collector level) -- the
-- pump must take two bounded steps to clear four objects, never one
-- unbounded sweep.
fn main() {
let a = Node { peers: multi_new(), p1: 0, p2: 0, p3: 0, p4: 0, p5: 0, p6: 0, p7: 0, p8: 0, p9: 0, p10: 0, p11: 0, p12: 0, p13: 0, p14: 0, p15: 0, p16: 0, p17: 0, p18: 0, p19: 0, p20: 0, p21: 0, p22: 0, p23: 0, p24: 0, p25: 0, p26: 0, p27: 0, p28: 0, p29: 0, p30: 0, p31: 0, p32: 0, p33: 0, p34: 0, p35: 0, p36: 0, p37: 0, p38: 0, p39: 0, p40: 0, p41: 0, p42: 0, p43: 0, p44: 0, p45: 0, p46: 0, p47: 0, p48: 0, p49: 0, p50: 0, p51: 0, p52: 0, p53: 0, p54: 0, p55: 0, p56: 0, p57: 0, p58: 0, p59: 0, p60: 0, p61: 0, p62: 0, p63: 0, p64: 0, p65: 0, p66: 0, p67: 0, p68: 0, p69: 0, p70: 0, p71: 0, p72: 0, p73: 0, p74: 0, p75: 0, p76: 0, p77: 0, p78: 0, p79: 0, p80: 0, p81: 0, p82: 0, p83: 0, p84: 0, p85: 0, p86: 0, p87: 0, p88: 0, p89: 0, p90: 0, p91: 0, p92: 0, p93: 0, p94: 0, p95: 0, p96: 0, p97: 0, p98: 0, p99: 0, p100: 0, p101: 0, p102: 0, p103: 0, p104: 0, p105: 0, p106: 0, p107: 0, p108: 0, p109: 0, p110: 0, p111: 0, p112: 0, p113: 0, p114: 0, p115: 0, p116: 0, p117: 0, p118: 0, p119: 0, p120: 0, p121: 0, p122: 0, p123: 0, p124: 0, p125: 0, p126: 0, p127: 0, p128: 0, p129: 0 }
let b = Node { peers: multi_new(), p1: 0, p2: 0, p3: 0, p4: 0, p5: 0, p6: 0, p7: 0, p8: 0, p9: 0, p10: 0, p11: 0, p12: 0, p13: 0, p14: 0, p15: 0, p16: 0, p17: 0, p18: 0, p19: 0, p20: 0, p21: 0, p22: 0, p23: 0, p24: 0, p25: 0, p26: 0, p27: 0, p28: 0, p29: 0, p30: 0, p31: 0, p32: 0, p33: 0, p34: 0, p35: 0, p36: 0, p37: 0, p38: 0, p39: 0, p40: 0, p41: 0, p42: 0, p43: 0, p44: 0, p45: 0, p46: 0, p47: 0, p48: 0, p49: 0, p50: 0, p51: 0, p52: 0, p53: 0, p54: 0, p55: 0, p56: 0, p57: 0, p58: 0, p59: 0, p60: 0, p61: 0, p62: 0, p63: 0, p64: 0, p65: 0, p66: 0, p67: 0, p68: 0, p69: 0, p70: 0, p71: 0, p72: 0, p73: 0, p74: 0, p75: 0, p76: 0, p77: 0, p78: 0, p79: 0, p80: 0, p81: 0, p82: 0, p83: 0, p84: 0, p85: 0, p86: 0, p87: 0, p88: 0, p89: 0, p90: 0, p91: 0, p92: 0, p93: 0, p94: 0, p95: 0, p96: 0, p97: 0, p98: 0, p99: 0, p100: 0, p101: 0, p102: 0, p103: 0, p104: 0, p105: 0, p106: 0, p107: 0, p108: 0, p109: 0, p110: 0, p111: 0, p112: 0, p113: 0, p114: 0, p115: 0, p116: 0, p117: 0, p118: 0, p119: 0, p120: 0, p121: 0, p122: 0, p123: 0, p124: 0, p125: 0, p126: 0, p127: 0, p128: 0, p129: 0 }
push(a.peers, b)
push(b.peers, a)
let c = Node { peers: multi_new(), p1: 0, p2: 0, p3: 0, p4: 0, p5: 0, p6: 0, p7: 0, p8: 0, p9: 0, p10: 0, p11: 0, p12: 0, p13: 0, p14: 0, p15: 0, p16: 0, p17: 0, p18: 0, p19: 0, p20: 0, p21: 0, p22: 0, p23: 0, p24: 0, p25: 0, p26: 0, p27: 0, p28: 0, p29: 0, p30: 0, p31: 0, p32: 0, p33: 0, p34: 0, p35: 0, p36: 0, p37: 0, p38: 0, p39: 0, p40: 0, p41: 0, p42: 0, p43: 0, p44: 0, p45: 0, p46: 0, p47: 0, p48: 0, p49: 0, p50: 0, p51: 0, p52: 0, p53: 0, p54: 0, p55: 0, p56: 0, p57: 0, p58: 0, p59: 0, p60: 0, p61: 0, p62: 0, p63: 0, p64: 0, p65: 0, p66: 0, p67: 0, p68: 0, p69: 0, p70: 0, p71: 0, p72: 0, p73: 0, p74: 0, p75: 0, p76: 0, p77: 0, p78: 0, p79: 0, p80: 0, p81: 0, p82: 0, p83: 0, p84: 0, p85: 0, p86: 0, p87: 0, p88: 0, p89: 0, p90: 0, p91: 0, p92: 0, p93: 0, p94: 0, p95: 0, p96: 0, p97: 0, p98: 0, p99: 0, p100: 0, p101: 0, p102: 0, p103: 0, p104: 0, p105: 0, p106: 0, p107: 0, p108: 0, p109: 0, p110: 0, p111: 0, p112: 0, p113: 0, p114: 0, p115: 0, p116: 0, p117: 0, p118: 0, p119: 0, p120: 0, p121: 0, p122: 0, p123: 0, p124: 0, p125: 0, p126: 0, p127: 0, p128: 0, p129: 0 }
let d = Node { peers: multi_new(), p1: 0, p2: 0, p3: 0, p4: 0, p5: 0, p6: 0, p7: 0, p8: 0, p9: 0, p10: 0, p11: 0, p12: 0, p13: 0, p14: 0, p15: 0, p16: 0, p17: 0, p18: 0, p19: 0, p20: 0, p21: 0, p22: 0, p23: 0, p24: 0, p25: 0, p26: 0, p27: 0, p28: 0, p29: 0, p30: 0, p31: 0, p32: 0, p33: 0, p34: 0, p35: 0, p36: 0, p37: 0, p38: 0, p39: 0, p40: 0, p41: 0, p42: 0, p43: 0, p44: 0, p45: 0, p46: 0, p47: 0, p48: 0, p49: 0, p50: 0, p51: 0, p52: 0, p53: 0, p54: 0, p55: 0, p56: 0, p57: 0, p58: 0, p59: 0, p60: 0, p61: 0, p62: 0, p63: 0, p64: 0, p65: 0, p66: 0, p67: 0, p68: 0, p69: 0, p70: 0, p71: 0, p72: 0, p73: 0, p74: 0, p75: 0, p76: 0, p77: 0, p78: 0, p79: 0, p80: 0, p81: 0, p82: 0, p83: 0, p84: 0, p85: 0, p86: 0, p87: 0, p88: 0, p89: 0, p90: 0, p91: 0, p92: 0, p93: 0, p94: 0, p95: 0, p96: 0, p97: 0, p98: 0, p99: 0, p100: 0, p101: 0, p102: 0, p103: 0, p104: 0, p105: 0, p106: 0, p107: 0, p108: 0, p109: 0, p110: 0, p111: 0, p112: 0, p113: 0, p114: 0, p115: 0, p116: 0, p117: 0, p118: 0, p119: 0, p120: 0, p121: 0, p122: 0, p123: 0, p124: 0, p125: 0, p126: 0, p127: 0, p128: 0, p129: 0 }
push(c.peers, d)
push(d.peers, c)
print_int(count(a.peers) + count(c.peers))
}