Skip to content

Fix #592: bare zero-arg included action reference now resolves - #637

Merged
logbie merged 2 commits into
mainfrom
claude/phase-2-language-correctness-xawgzx
Jul 19, 2026
Merged

Fix #592: bare zero-arg included action reference now resolves#637
logbie merged 2 commits into
mainfrom
claude/phase-2-language-correctness-xawgzx

Conversation

@logbie

@logbie logbie commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #592 by making bare references to zero-argument included actions resolve consistently with the of and call forms. Previously, store x as greet (where greet is a zero-arg action from an included file) was a fatal analyze error, while call greet and greet of "x" worked. This was the last surviving form of the main-vs-include inconsistency Phase 2 aims to eliminate.

Changes

Analyzer (src/analyzer/mod.rs)

  • Modified the Expression::Variable arm in analyze_expression to route unresolved, non-container-property names through the existing warn_undefined_callee_if_includes helper (the same relaxation used by of/call forms)
  • Only falls back to the fatal report_undefined_name when the helper returns false (no includes present)
  • Preserves fatal errors for genuine typos in programs without include from
  • Added two unit tests: one verifying the relaxation fires with includes, one guardrailing that it stays fatal without includes

Tests (tests/phase1_correctness_regression_test.rs)

Test Programs

  • Added TestPrograms/module_include_bare_zero_arg.wfl (end-to-end fixture exercising bare reference at top level and inside an action body)
  • Added TestPrograms/module_bare_zero_arg_helper.wfl (helper module exposing a zero-arg action)
  • Updated both scripts/run_integration_tests.sh and .ps1 to skip the helper module

Documentation (Docs/04-advanced-features/modules.md)

  • Added "Calling actions from an included file" subsection documenting all three call forms
  • Explains that zero-argument included actions are referenced by bare name
  • Honestly notes the non-fatal Undefined action warning the analyzer emits for statically-invisible names

Dev Diary

  • Added Dev diary/2026-07-18-issue-592-bare-zero-arg-include.md documenting the root cause, fix, regression protection, and compatibility

Implementation Details

The root cause was that a bare reference (store x as greet) lowers to Expression::Variable with no call node, so it never reached the include-aware relaxation that of and call forms already used. The fix reuses the exact same helper (warn_undefined_callee_if_includes) that #580 unified those two forms onto, ensuring all three call forms cannot drift apart again.

Behavior after the fix:

  • Bare reference with include from → non-fatal Undefined action warning, runs, exit 0
  • Bare reference without include from → fatal Variable '…' is not defined, exit 3 (unchanged)

Backward compatible: only relaxes a currently-fatal error when include from is present; preserves the fatal path for all other cases.

https://claude.ai/code/session_01Ku1nQWnpSBgVXMNNVZ3Qhm


Open in Devin Review

Summary by CodeRabbit

  • Bug Fixes

    • Fixed analysis errors when calling zero-argument actions from included files by bare name.
    • Included actions now run successfully while showing a non-fatal undefined-action warning when static analysis cannot resolve them.
    • Undefined names without included files continue to produce fatal errors.
  • Documentation

    • Added guidance for calling actions from included files using supported syntax and bare names.

…#592)

A zero-argument action exposed by an `include from` file and referenced by
its bare name (`store x as greet`) was a fatal `Variable '<name>' is not
defined` analyze error at top level and inside action bodies, while the `of`
and `call` forms already worked across an include. A bare reference lowers to
`Expression::Variable` with no call node, so it never reached the include-aware
relaxation `warn_undefined_callee_if_includes` that #580 unified the `of`
(`FunctionCall`) and `call` (`ActionCall`) forms onto — the third and last
surviving form of the #548 -> #580 family.

Route the `Expression::Variable` arm through that same helper: when the name is
unresolved (and not a container property) and the program uses `include from`,
emit a non-fatal `Undefined action` warning instead of aborting. With no
includes present the helper returns false, so a genuine typo stays fatal. The
type checker already returns Unknown for such a name and the interpreter already
auto-calls a bare zero-arg action, so this analyzer relaxation is the only
change needed. Backward compatible: it only relaxes a currently-fatal error.

Production-readiness area: Correctness (#610 Phase 2 — consistent main/include
semantics).

Tests / docs:
- analyzer unit tests: with-include relaxes to a warning; no-include stays fatal
- un-ignore the phase1 issue_592_* acceptance tests (top level + action body);
  add an issue_592 no-include fatal guardrail; update the Phase 1 coverage map
- TestPrograms/module_include_bare_zero_arg.wfl end-to-end fixture (+ helper,
  skip-listed in both integration harness scripts)
- Docs/04-advanced-features/modules.md: new "Calling actions from an included
  file" subsection documenting all three call forms; Dev Diary entry

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ku1nQWnpSBgVXMNNVZ3Qhm
Copilot AI review requested due to automatic review settings July 18, 2026 18:38
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8fc17f2-4893-4a3d-9b85-ef57e739e125

📥 Commits

Reviewing files that changed from the base of the PR and between 187086d and be7d7d4.

📒 Files selected for processing (8)
  • Dev diary/2026-07-18-issue-592-bare-zero-arg-include.md
  • Docs/04-advanced-features/modules.md
  • TestPrograms/module_bare_zero_arg_helper.wfl
  • TestPrograms/module_include_bare_zero_arg.wfl
  • scripts/run_integration_tests.ps1
  • scripts/run_integration_tests.sh
  • src/analyzer/mod.rs
  • tests/phase1_correctness_regression_test.rs

📝 Walkthrough

Walkthrough

The analyzer now treats unresolved bare names as possible zero-argument included actions, emitting a non-fatal warning when includes exist while retaining fatal errors otherwise. Regression fixtures, active tests, integration skips, and module documentation cover the behavior.

Changes

Bare zero-argument include resolution

Layer / File(s) Summary
Include-aware bare-name analysis
src/analyzer/mod.rs
Unresolved bare names use warn_undefined_callee_if_includes when includes exist; otherwise Variable 'greet' is not defined remains fatal, with unit tests for both paths.
Regression fixtures and active guards
TestPrograms/*, tests/phase1_correctness_regression_test.rs, scripts/run_integration_tests.*
Added included-module fixtures, enabled the top-level and action-body issue #592 tests, added a no-include guard, and skipped helper modules during integration execution.
Behavior documentation
Docs/04-advanced-features/modules.md, Dev diary/*
Documented included-action invocation forms, analyzer warnings, compatibility behavior, and the issue resolution.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main fix for bare zero-arg included action references.
Linked Issues check ✅ Passed The analyzer change, regression tests, fixtures, and docs address #592 by resolving bare included zero-arg actions with a warning.
Out of Scope Changes check ✅ Passed All additions are directly tied to the #592 fix; no unrelated code changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/phase-2-language-correctness-xawgzx

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #592 by making bare references to zero-argument actions exposed via include from (e.g. store x as greet) resolve the same way as the existing call greet and greet of ... forms, eliminating a remaining main-vs-include inconsistency in the analyzer.

Changes:

  • Analyzer: routes unresolved Expression::Variable names through the existing include-aware undefined-callee relaxation helper, falling back to a fatal undefined-name error only when no includes exist.
  • Tests: enables the previously ignored #592 regression tests, adds guardrails to ensure the relaxation stays fatal when no include from is present, and adds an end-to-end TestPrograms/ fixture.
  • Docs/Dev diary: documents the three call forms for included actions and records the fix rationale.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/analyzer/mod.rs Extends include-aware undefined-name relaxation to bare Expression::Variable references; adds focused unit tests.
tests/phase1_correctness_regression_test.rs Activates #592 regression tests and adds a no-include fatal guardrail.
TestPrograms/module_include_bare_zero_arg.wfl End-to-end fixture covering bare zero-arg included action references (top-level + inside action body).
TestPrograms/module_bare_zero_arg_helper.wfl Helper module providing a zero-arg action used by the fixture (skip-listed).
scripts/run_integration_tests.sh Skip-lists the helper module so it isn’t executed as a standalone program.
scripts/run_integration_tests.ps1 Same skip-list update for Windows runs.
Docs/04-advanced-features/modules.md Adds a subsection documenting included-action invocation forms (bare / of / call ... with).
Dev diary/2026-07-18-issue-592-bare-zero-arg-include.md Dev diary entry explaining root cause, fix, and regression coverage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

display line
```

All three forms work at the top level and inside your own action bodies. Because the analyzer does not read included files, it emits a **non-fatal** `Undefined action '<name>'` note for a name it cannot see statically — the program still runs and the action resolves at runtime.
Comment thread src/analyzer/mod.rs
Comment on lines +2569 to +2573
// no includes present the helper emits nothing and
// returns false, so a genuine typo stays fatal.
if !self.warn_undefined_callee_if_includes(name, *line, *column) {
self.report_undefined_name(
format!("Variable '{name}' is not defined"),
Comment on lines +39 to +41
warning (the action may be exposed by the included file at runtime, which the
analyzer never reads) and returns `true`; with no includes it emits nothing and
returns `false`, preserving the fatal path so genuine typos stay caught.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b75bba1501

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/analyzer/mod.rs
// consistently under `include from` (issue #592). With
// no includes present the helper emits nothing and
// returns false, so a genuine typo stays fatal.
if !self.warn_undefined_callee_if_includes(name, *line, *column) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep include relaxation from covering all bare variables

When a program contains any include from, this branch now downgrades every unresolved bare variable expression to a non-fatal Undefined action warning, not just the intended zero-arg action reference. In an include-using file, a genuine typo such as check if no: display misspelled_name end check now only warns and exits 0 because the branch is skipped at runtime, whereas it previously failed analysis with Variable 'misspelled_name' is not defined; this can let undefined-variable bugs pass CI in any program that happens to include a module.

Useful? React with 👍 / 👎.

Copilot AI review requested due to automatic review settings July 19, 2026 02:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/analyzer/mod.rs:2573

  • warn_undefined_callee_if_includes emits Undefined action '<name>', but in the Expression::Variable path the unresolved bare name can also be a variable/constant supplied by an included file (not necessarily an action). This warning text (and the static note that follows from it) can therefore be misleading once includes are present.
                        // A bare unresolved name may be a zero-argument action
                        // exposed by an `include from` file and referenced by
                        // its bare name (e.g. `store x as greet`), which lowers
                        // to `Expression::Variable` with no call node and so
                        // never reaches the `of`/`call` forms' include-aware
                        // relaxation. Route it through the same helper so all
                        // three call forms of the #548 -> #580 family behave
                        // consistently under `include from` (issue #592). With
                        // no includes present the helper emits nothing and
                        // returns false, so a genuine typo stays fatal.
                        if !self.warn_undefined_callee_if_includes(name, *line, *column) {
                            self.report_undefined_name(
                                format!("Variable '{name}' is not defined"),

Docs/04-advanced-features/modules.md:76

  • This sentence says the analyzer does not read included files, but include from does parse/analyze/type-check the included file at runtime; the real limitation is that symbols from included files are not available when analyzing the including file. Reword to avoid an inaccurate claim.
All three forms work at the top level and inside your own action bodies. Because the analyzer does not read included files, it emits a **non-fatal** `Undefined action '<name>'` note for a name it cannot see statically — the program still runs and the action resolves at runtime.

@logbie
logbie merged commit 13733fe into main Jul 19, 2026
17 checks passed
@logbie
logbie deleted the claude/phase-2-language-correctness-xawgzx branch July 19, 2026 02:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants