Add actionable hint for undefined symbols in load-module programs - #586
Conversation
…include from (#584) `load module from "..."` runs a file in an isolated child scope and, by design, does not expose its actions/containers/variables to the caller — `include from` is the mechanism that shares definitions. A caller that references a load-module-defined action was therefore correctly rejected, but with an opaque `Variable '...' is not defined` (exit 3) that gave no hint toward the fix. The issue's suggested fix (register module symbols in the analyzer, or relax the error to a warning like the include path) is wrong here: verified empirically, such a reference also fails at runtime, so relaxing analysis would let the program past the analyzer only to crash later — trading a clear compile-time error for a confusing runtime one. Instead keep the fatal error (the program genuinely cannot run) but make it actionable: when a file uses `load module`, an undefined action/variable diagnostic now carries a note explaining the isolation and pointing at `include from`. No semantics change, no backward-compat risk — all 103 integration tests still pass. - add `program_has_load_module` helper alongside `program_has_includes` - attach the guidance note in `analyze_static` for undefined-symbol errors - tests/load_module_undefined_hint_test.rs: fatal+hint for of/call forms, hint under --analyze, include-from resolves and runs, and no hint when no load module is present - Docs/04-advanced-features/modules.md: document the diagnostic guidance Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAtsuADakMwNuDy6n3967r
…584) Add an at-a-glance table and a prominent "common mistake" callout at the top of the modules guide, so readers pick `include from` for shared libraries and `load module` for side-effect-only files. This is the confusion behind #584 (referencing an action from a `load module`d file), now also surfaced by an actionable analyzer diagnostic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAtsuADakMwNuDy6n3967r
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a ChangesLoad module diagnostic hint
Estimated code review effort: 2 (Simple) | ~15 minutes Sequence Diagram(s)sequenceDiagram
participant Program
participant Analyzer as Analyzer::analyze_static
participant Detector as program_has_load_module
participant Diagnostic as WflDiagnostic
Program->>Analyzer: analyze(program)
Analyzer->>Detector: program_has_load_module(program)
Detector-->>Analyzer: true/false
Analyzer->>Analyzer: classify error as undefined action/variable
Analyzer->>Diagnostic: new(error, note)
Diagnostic-->>Program: fatal diagnostic with include-from hint
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
tests/load_module_undefined_hint_test.rs (1)
143-163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMissing guard-rail test for mixed load-module + unrelated-typo case.
Given the note-attachment logic in
static_analyzer.rsapplies the hint to any undefined-symbol error wheneverload moduleis present anywhere in the file, it would be valuable to add a test asserting the hint still fires (correctly or not) when the undefined symbol is unrelated to the loaded module, to pin the current behavior.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/load_module_undefined_hint_test.rs` around lines 143 - 163, Add a guard-rail test in undefined_without_load_module_has_no_include_hint or a nearby test that covers a file containing load module plus an unrelated undefined of-callee, using run_file_status and checking the static_analyzer.rs note-attachment behavior. The test should assert whether the include from hint is present for the mixed case so the current undefined-symbol hint behavior stays pinned when load module appears anywhere in the file.src/analyzer/static_analyzer.rs (1)
158-165: 🎯 Functional Correctness | 🔵 Trivial | ⚖️ Poor tradeoffNote is attached to any undefined-symbol error whenever
load moduleappears anywhere in the file, not just symbols tied to the loaded module.If a file legitimately uses
load modulefor side effects and separately has an unrelated typo (e.g., a misspelled local variable), this note will still fire, telling the user to useinclude from— which wouldn't fix the typo. This is a coarse heuristic; consider scoping the check to whether the undefined name is a plausible export of the loaded file, if that information is available to the analyzer.Also applies to: 183-201
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/analyzer/static_analyzer.rs` around lines 158 - 165, The undefined-symbol note is currently triggered too broadly by program_has_load_module, so it gets attached to unrelated typos whenever any load module exists in the file. Update the static_analyzer logic around the undefined-symbol handling to scope the note more precisely—ideally only when the missing name is plausibly an export from the loaded module, or otherwise when the error is actually related to the loaded file. Use the existing has_load_module check and the undefined-symbol path in static_analyzer to narrow when the “include from” guidance is emitted, including the same adjustment in the later matching block referenced by the analyzer comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/analyzer/static_analyzer.rs`:
- Around line 158-165: The undefined-symbol note is currently triggered too
broadly by program_has_load_module, so it gets attached to unrelated typos
whenever any load module exists in the file. Update the static_analyzer logic
around the undefined-symbol handling to scope the note more precisely—ideally
only when the missing name is plausibly an export from the loaded module, or
otherwise when the error is actually related to the loaded file. Use the
existing has_load_module check and the undefined-symbol path in static_analyzer
to narrow when the “include from” guidance is emitted, including the same
adjustment in the later matching block referenced by the analyzer comment.
In `@tests/load_module_undefined_hint_test.rs`:
- Around line 143-163: Add a guard-rail test in
undefined_without_load_module_has_no_include_hint or a nearby test that covers a
file containing load module plus an unrelated undefined of-callee, using
run_file_status and checking the static_analyzer.rs note-attachment behavior.
The test should assert whether the include from hint is present for the mixed
case so the current undefined-symbol hint behavior stays pinned when load module
appears anywhere in the file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 18b22426-c6f9-4950-9394-8c76ba144d32
📒 Files selected for processing (4)
Docs/04-advanced-features/modules.mdsrc/analyzer/mod.rssrc/analyzer/static_analyzer.rstests/load_module_undefined_hint_test.rs
…typos (#584) Addresses CodeRabbit review on #586: the include-from note fires for any undefined-symbol error whenever a file uses `load module`, without parsing the loaded file to confirm the missing name is one of its exports. Rather than add that heavyweight module resolution to the analyzer, reword the note conditionally ("If you expected this name to come from a file loaded with `load module` ...") so it is a correct fix for a real module symbol while not misleading a plain typo in a side-effect-only load. - reword the note in static_analyzer.rs (behavior/trigger unchanged) - pin the mixed load-module + unrelated-typo case with a new guard-rail test - update the documented error snippet to match Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAtsuADakMwNuDy6n3967r
|
Thanks @coderabbitai — both nitpicks addressed in d3b4368. On the coarse-trigger point: the note does fire for any undefined symbol when a file uses Instead I reworded the note to be conditionally framed so it can't mislead a plain typo:
For a real module symbol it's the fix; for an unrelated typo the "if you expected…" clause simply doesn't apply, so the primary (Note: the Generated by Claude Code |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
cd /repo 2>/dev/null || true
git log --oneline -5 2>/dev/null
git show d3b4368 --stat 2>/dev/null | head -50Length of output: 1996
Agreed the Copilot reviewer failure (HTTP 402 quota) is unrelated to this diff — no action needed there. ᐡ˵•ᴥ•˵ᐡ |
Summary
When a WFL program uses
load moduleand references an undefined action or variable, the analyzer now attaches an actionable note explaining thatload moduleruns in an isolated scope and suggestinginclude fromas the correct alternative. This addresses issue #584 by making a fatal error (which correctly cannot be relaxed) more helpful to users.Key Changes
Analyzer enhancement (
src/analyzer/static_analyzer.rs):load modulestatementsload moduleis isolated and recommendinginclude fromas the mechanism to share definitionsHelper function (
src/analyzer/mod.rs):program_has_load_module()to detect top-levelload modulestatementsprogram_has_includes()patternDocumentation update (
Docs/04-advanced-features/modules.md):include from(to share libraries) vs.load module(for side-effect-only files)load moduleisolation is intentional and documentedComprehensive test suite (
tests/load_module_undefined_hint_test.rs):load moduleare invisible to the static analyzer (fatal "not defined") #584 (bothof-form andcall-form references)--analyzeinclude fromis the working alternativeload moduleis present (not for unrelated undefined-symbol errors)Implementation Details
The fix leverages the fact that
load moduleisolation is by design — a caller referencing a loaded module's definition fails at runtime too, not only in the analyzer. Rather than relaxing the error (which would be wrong), the solution keeps it fatal but makes it actionable by pointing users at the correct mechanism (include from) that actually shares definitions across files.The hint is only shown when the program contains a
load modulestatement, avoiding false guidance for unrelated undefined-symbol errors.https://claude.ai/code/session_01RAtsuADakMwNuDy6n3967r
Summary by CodeRabbit
Documentation
Bug Fixes
load module fromleads to missing actions or variables, pointing to the correct way to share definitions.Tests
--analyzebehavior, and successful behavior when using the shared-definition approach.