code wiki / (root) / nx_macro_argcap_probe.nx

nx_macro_argcap_probe.nx source

↩ module page · 33 lines · 1601 B

1// nx_macro_argcap_probe.nx -- NEGATIVE CONTROL for the >8-argument macro refusal (debt 1785521154). 2// 3// THIS FILE MUST FAIL TO BUILD. It is not a gate; it is the proof that the tooth BITES. 4// 5// The macro below declares NINE parameters. Before the fix, only the first 8 were registered, so the 6// 9th parameter name `i` was never recognised inside the body -- it fell through to the copy-verbatim 7// branch and was emitted as the LITERAL identifier `i`. Because a variable named `i` IS in scope at the 8// call site, that produced a program which COMPILED AND RAN, returning the wrong value (7, the local i) 9// instead of 9. A silent miscompile with no diagnostic. 10// 11// After the fix, lexm_subst REFUSES the whole expansion, emits nothing, and the macro name survives to 12// the parser -- so the build fails LOUDLY with `undefined function: ARGCAP9`. 13// 14// EXPECTED: BUILD-FAILED with an undefined-function error naming ARGCAP9, plus the nx_tokenizer stderr 15// warning naming the argument count. A SUCCESSFUL BUILD MEANS THE FIX REGRESSED. 16// expect_exit: nonzero-build license_tier: ORIGINAL 17 18import "nx_kernel_v2.nx" 19 20@macro ARGCAP9(a, b, c, d, e, f, g, h, i) (i) 21 22func argcap_probe() -> nx_int { 23 let i: nx_int = 7 24 return ARGCAP9(1, 2, 3, 4, 5, 6, 7, 8, 9) 25} 26 27func main() -> nx_exit { 28 let v: nx_int = argcap_probe() 29 if v == 7 { println("SILENT MISCOMPILE: expansion used the in-scope i, not the 9th argument" as *u8); return 1 } 30 if v == 9 { println("9-arg macro expanded correctly (cap was raised?)" as *u8); return 0 } 31 println("unexpected value" as *u8) 32 return 2 33}