feat(compile): add --trace/--focus debugging flags#1738
Merged
Conversation
Consolidate the scattered compiler-introspection knobs into one CLI
surface and add a focus filter for localizing "compiled to the wrong
thing" bugs.
- `--trace <stages>`: comma-separated `hir`, `llvm`, or `all`.
- `hir` dumps post-transform HIR (same data as `--print-hir`).
- `llvm` wires up PERRY_SAVE_LL + PERRY_LLVM_KEEP_IR to write
per-module .ll into `.perry-trace/llvm/`, and forces PERRY_NO_CACHE
for the build so the object cache can't skip codegen and leave the
trace dir empty.
- `--focus <name>`: substring filter on `--trace hir`, restricting
output to matching functions / class methods / classes and
suppressing import/export/init noise (one function's body is ~40
lines instead of buried in a full-module dump). Implies `hir` when no
stage is given.
`--print-hir` keeps its exact historical full-dump behavior (focus
None). `dump_hir_for_debug` now takes an `Option<&str>` focus arg and
shares a `dump_hir_function` helper between free functions and methods.
Adds `.perry-trace/` to .gitignore and documents the flags in
docs/src/cli/flags.md.
Make the new debug flags discoverable to future LLM sessions, which load CLAUDE.md for orientation. Adds them next to --print-hir and a short note to reach for --trace hir --focus <fn> when localizing a miscompile. Version line untouched (worktree-PR convention).
4 tasks
proggeramlug
added a commit
that referenced
this pull request
May 25, 2026
7 PRs landed on main after the v0.5.1027 bump (50c391f) without per-PR tags. Neither v0.5.1026 nor v0.5.1027 were tagged on the remote — v0.5.1028 is the first tag in this window. - #1738 feat(compile): --trace/--focus debugging flags. - #1723/#1741 fix(lockdown): #503 ns[dynamicKey].staticMember. - #1673/#1742 fix(dynamic-import): literal node: builtin specifier. - #1724/#1747 fix(node): Blob/URL globals trigger http-client feature. - #1728/#1749 fix(node:path): win32 normalize/basename/toNamespacedPath. - #1751 test(parity): stream consumers/promises/static batch. - #1754 test(node-core): enrich common shim for #800.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
--trace/--focusdebug flags that consolidate the scatteredcompiler-introspection knobs (
--print-hir,PERRY_SAVE_LL,PERRY_LLVM_KEEP_IR) into one CLI surface, plus a focus filter forlocalizing "compiled to the wrong thing" bugs — the dominant Perry debug
workflow.
--trace <stages>— comma-separatedhir,llvm, orall.hir: post-transform HIR dump (same data as--print-hir).llvm: writes per-module.llinto.perry-trace/llvm/by promotingthe
PERRY_SAVE_LL/PERRY_LLVM_KEEP_IRenv vars, and forcesPERRY_NO_CACHEso the per-module object cache can't skip codegen andleave the trace dir empty (the same cache-bypass
--verify-native-regionsalready does).
--focus <name>— substring filter on--trace hir: only matchingfunctions, class methods, and classes are printed, and the
imports/exports/init sections are suppressed. One function's lowered body
is ~40 lines instead of buried in a 10k-line full-module dump. Implies
hirwhen no stage is given.--print-hirkeeps its exact historical full-dump behavior (it maps tofocus = None).Why
When a TypeScript program compiles to the wrong result, ~30% of debug time
is just localizing which stage corrupted a value. The pipeline has clean
stage boundaries but the introspection for them was a scattered set of
undocumented env vars. This makes "dump stage X, focused on function Y" a
one-liner.
Test evidence
Verified manually:
--trace hir --focus NAME→ focused dump (functions + matching class methods)--focus NAMEalone → implies hir--trace llvm→.perry-trace/llvm/*.llwritten (cache-bypass confirmed)--trace all→ full HIR + llvm--print-hir→ unchanged full dump (imports/exports/init present)cargo fmt --all -- --checkclean; new code clippy-clean;cargo build -p perry --testsclean.Scope / follow-ups (deliberately out of this slice)
--focuson the LLVM stage (extract just the matchingdefines post-codegen)aststage (pre-lowering SWC dump)--timings(per-stage wall time)Per worktree-PR convention this PR omits the version bump + CHANGELOG entry;
fold those in at merge.