{"atom":"regression/who-stash-and-export-slots","family":"regression","slug":"who-stash-and-export-slots","header":{"atom":"regression/who-stash-and-export-slots","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/who-stash-and-export-slots.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/who-stash-and-export-slots.grid"],"records":[["0001","","# From the v2 module battery: three modules died at load time on package-stash\n# writes rakupp could not represent —\n#\n#   Advent::GrammarProfiler   EXPORTHOW.WHO.<grammar> = ProfiledGrammarHOW\n#   Sparrow6::DSL             BEGIN for <&a &b> { EXPORT::DEFAULT::{$_} = ::($_) }\n#   RuntimeCreatedPackage     ::GLOBAL.WHO<X> := Metamodel::PackageHOW.new_type(…)\n#\n# The root cause was one thing: `.WHO` built a FRESH empty Hash on every call, so\n# there was nothing persistent to assign into (\"Target is not assignable\"). WHO\n# now answers one shared stash per package name, the lvalue path routes\n# assignment through it, and `Foo::{EXPR}` (runtime key) desugars to WHO.\n# Contract: exit 0 + last line PASS.\nmy @fail;\nsub check($got, $want, $what) { @fail.push(\"$what: got {$got.raku} want {$want.raku}\") unless $got eqv $want }\n\n# the stash persists across calls — this is the heart of the bug\nmy module M {}\nM.WHO.<x> = 42;\ncheck(M.WHO.<x>, 42, '.WHO.<k> assigns and reads back');\nM.WHO.<x> = 43;\ncheck(M.WHO.<x>, 43, 'and re-assigns through the same stash');\n\n# both slot syntaxes see each other's writes\ncheck(M::<x>, 43, 'Foo::<k> reads a WHO-written symbol');\nmy $k = 'dyn';\nM::{$k} = 'via-brace';\ncheck(M.WHO.<dyn>, 'via-brace', 'Foo::{EXPR} writes with a runtime key');\n\n# the Sparrow6 shape: re-export by stash assignment in a BEGIN loop\nsub helper-a { 'A' }\nsub helper-b { 'B' }\nmy package EXPORT::DEFAULT {}\nBEGIN for <&helper-a &helper-b> { EXPORT::DEFAULT::{$_} = ::($_) }\ncheck(EXPORT::DEFAULT::{'&helper-a'}.defined, True, 'the BEGIN re-export loop populates the stash');\ncheck(EXPORT::DEFAULT::{'&helper-b'}(), 'B', 'and the stored sub is callable');\n\n# the GLOBAL shape from roast's RuntimeCreatedPackage\n# (read back through WHO — `GLOBAL::<x>` routes through the pseudo-package\n# machinery, a separate path this fix does not touch)\n::GLOBAL.WHO<CreatedAtRuntime> := Metamodel::PackageHOW.new_type(name => 'CreatedAtRuntime');\ncheck(::GLOBAL.WHO<CreatedAtRuntime>.^name, 'CreatedAtRuntime', 'a runtime package binds into GLOBAL.WHO');\n\nif @fail { note \"FAILED:\\n\" ~ @fail.join(\"\\n\"); say 'FAIL' } else { say 'PASS' }","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}