{"atom":"regression/callable-context-callme-raw","family":"regression","slug":"callable-context-callme-raw","header":{"atom":"regression/callable-context-callme-raw","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/callable-context-callme-raw.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/callable-context-callme-raw.grid"],"records":[["0001","","# Regression: three general fixes from the zef-bar campaign's first batch\n# (dist test suites as the compatibility standard; zero-dep modules first).\n#\n# 1. `&(EXPR)` — the parenthesised Callable contextualizer — was a parse error\n#    (\"unexpected operator in term position\"); Encode dispatches every decode\n#    through `&(%encodings{$encoding})($buf)`, so the WHOLE dist failed 0/7.\n#    Also accepted as a listop argument (`say &(...)()` went nullary-say).\n# 2. A class with CALL-ME called BY NAME (`Trap(my $*OUT)`) threw \"Undefined\n#    routine\" — the named-call path never consulted the class; now it\n#    dispatches to CALL-ME ahead of the T(x) coercion protocol, with the\n#    call's arg exprs as rwArgs so write-back works.\n# 3. `is raw` params never wrote back (subs, methods, anywhere) — only `is rw`\n#    did; and an explicit `C:U:` invocant param consumed a slot in the\n#    rw-pairing loops, shifting every later write-back off by one.\n# Together: Encode 0/7 -> 7/7 and Trap 0/2 -> 2/2 on their own suites.\n# Contract: exit 0 + last line PASS.\nmy @fail;\n\n# 1. &(EXPR) in statement, assignment, and listop-argument positions\nmy %disp = double => sub ($n) { $n * 2 }, negate => sub ($n) { -$n };\nmy $r1 = &(%disp<double>)(21);\n@fail.push(\"assign: $r1\") unless $r1 == 42;\n@fail.push('listop') unless \"{&(%disp<negate>)(5)}\" eq '-5';\nmy @collected;\n@collected.push(&(%disp{$_})(10)) for <double negate>;\n@fail.push(\"loop: @collected[]\") unless @collected eqv [20, -10];\n\n# 2. CALL-ME by name, plain and multi, beats coercion; coercion still works\nclass Adder {\n    has $.base;\n    multi method CALL-ME(Adder:U: $n) { $n + 1 }\n    multi method CALL-ME(Adder:U: $n, $m) { $n + $m }\n}\n@fail.push('callme-1') unless Adder(41) == 42;\n@fail.push('callme-2') unless Adder(40, 2) == 42;\n\n# 3. is raw write-back: sub, method, multi CALL-ME with explicit invocant +\n#    trailing named param (the Trap shape), and a dynamic-var argument\nsub set-raw($x is raw) { $x = 'sub-ok' }\nset-raw(my $a);\n@fail.push(\"sub raw: {$a // 'undef'}\") unless $a eq 'sub-ok';\n\nclass Setter {\n    method fill($x is raw) { $x = 'meth-ok' }\n    multi method CALL-ME(Setter:U: $x is raw, :$opt) { $x = 'callme-ok'; True }\n}\nSetter.fill(my $b);\n@fail.push(\"method raw: {$b // 'undef'}\") unless $b eq 'meth-ok';\nSetter(my $c);\n@fail.push(\"invocant+raw: {$c // 'undef'}\") unless $c eq 'callme-ok';\nSetter(my $*DYN);\n@fail.push(\"dynamic raw: {$*DYN // 'undef'}\") unless $*DYN eq 'callme-ok';\n\n# read-only use of a raw param stays fine\nsub peek($x is raw) { $x + 1 }\n@fail.push('raw read') unless peek(5) == 6;\n\nif @fail { note \"FAILED:\\n\" ~ @fail.join(\"\\n\"); say 'FAIL' }\nelse     { say 'PASS' }","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}