2 ms·
nice job! so i tried around and so far am impressed, anyhow: \newcommand{\foo}[1]{\bar{#1}} \renewcommand{\bar}[1]{\foo{#1}} % mutual recursion \foo{x} \def\x
by holg 9mo ago
nice job! so i tried around and so far am impressed,
anyhow:
\newcommand{\foo}[1]{\bar{#1}}
\renewcommand{\bar}[1]{\foo{#1}} % mutual recursion
\foo{x}
\def\x{\y}\def\y{z}\x % chained expansion
+>
#set page(paper: "a4")
#set heading(numbering: "1.")
#set math.equation(numbering: "(1)")
/* \foo /
/ \y /
\foo{x} → \bar{x} → \foo{x} → ∞
Expected: hit depth limit, emit warning, output either x or the unexpanded \foo{x}
Actual: / \foo */ — silently converted to a comment, lost the argument x entirely
- democat 9mo agoThanks for the stress test! You are absolutely right, and I really appreciate you catching this edge case. I've traced the issue in the codebase: 1. The recursion depth limit *is* triggering correctly (preventing an infinite loop). 2. However, when it bails out, it returns the partially expanded macro call (e.g., `\foo{x}`). 3. Since the macro definition was removed during the preprocessing step, the parser then sees `\foo` as an unknown command and converts it into an error comment, accidentally discarding the argument `{x}` in the process. *The intended behavior* should definitely be to preserve the content (the `x`) even if the macro logic fails. I will fix the fallback logic to ensure it fails gracefully without eating the arguments. Thanks again for the sharp eye! These kinds of checks are super helpful.