Skip to content

Conversation

@lukewilliamboswell
Copy link
Collaborator

Fixes #8942

This PR fixes a stack overflow that occurred when the compiler processed self-referential variable definitions like a = a. The compiler would enter infinite recursion when trying to evaluate such definitions.

  • Added cycle detection to evalLookupLocal for top-level definitions using the existing def_stack mechanism
  • When a lookup encounters a definition already being evaluated, it either creates a placeholder for recursive functions or triggers a crash with a clear error message for non-function circular references
  • Added a regression test to verify the fix

Co-authored by Claude Opus 4.5

@lukewilliamboswell lukewilliamboswell marked this pull request as ready for review January 8, 2026 04:18
@lukewilliamboswell
Copy link
Collaborator Author

@rtfeldman I wonder if this and similar checks should occur in Can instead of at runtime...?

@rtfeldman
Copy link
Contributor

@lukewilliamboswell Yeah for sure that's where they should happen - I'm surprised they don't already...I thought that had already been implemented, but I guess not? Anyway, what we definitely want to happen is:

  • Canonicalization detects this
  • If it's detected, the entire assignment gets replaced with an Error node
  • If the interpreter reaches that node, it crashes.

lukewilliamboswell and others added 2 commits January 9, 2026 12:29
Add cycle detection to evalLookupLocal for top-level definitions to
prevent infinite recursion when a variable references itself (e.g., a = a).

The fix adds tracking of definitions currently being evaluated using
the existing def_stack mechanism. When a lookup encounters a definition
that is already in progress, it either creates a placeholder for
recursive functions or triggers a crash with a clear error message
for non-function circular references.

Also adds a regression test for issue #8942.

Co-Authored-By: Claude <noreply@anthropic.com>
Based on PR feedback, circular definitions like `a = a` are now detected
during type checking rather than at runtime in the interpreter.

Changes:
- Add `circular_def` problem type to Check with clear error message
- Detect circular non-function definitions in the `.processing` case
  when checking local lookups
- Allow recursive functions (lambdas and closures) to reference themselves
- Keep runtime check as safety net for edge cases

The compile-time check provides better error messages and catches the
issue earlier in the compilation pipeline.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Detect circular definitions like `a = a` at compile time in canonicalization
rather than at runtime. When a non-lambda expression references its own
defining pattern, the reference is replaced with a runtime error node.

This prevents stack overflows and provides a clear error message:
"INVALID ASSIGNMENT TO ITSELF"

Fixes #8942

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@lukewilliamboswell lukewilliamboswell marked this pull request as ready for review January 9, 2026 02:22
@lukewilliamboswell
Copy link
Collaborator Author

@rtfeldman moved the logic into Can instead 👍

@lukewilliamboswell lukewilliamboswell merged commit 72b91ec into main Jan 10, 2026
35 checks passed
@lukewilliamboswell lukewilliamboswell deleted the fix-issue-8942 branch January 10, 2026 03:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The Roc compiler overflowed its stack memory and had to exit

3 participants