Skip to content

fix: stack overflow when a for loop's iterable references its own loop variable - #440

Open
garretfick wants to merge 1 commit into
withered-magic:mainfrom
garretfick:main
Open

garretfick wants to merge 1 commit into
withered-magic:mainfrom
garretfick:main

Conversation

@garretfick

Copy link
Copy Markdown

Fixes #439.

When collecting scopes, for statements declared their loop variables in the same scope in which the iterable expression had been collected, unlike assignments and comprehensions which allocate a fresh scope first. As a result, a name used in the iterable resolved to the loop variable itself. Inferring the type of the loop variable then required inferring the iterable, which required inferring the loop variable again, and so on until the stack overflowed. This is triggered by code such as:

for idl in idls:
    for idl in idl.idl_files:
        ...

which appears in rules_ros2's ament.bzl and crashed the server whenever that file was analyzed, e.g. after go-to-definition on py_exec_launcher.

The iterable is evaluated before the loop variables are bound, so allocate a new scope for the targets. Names in the iterable now resolve to the enclosing definition (or report "not defined" if there is none).

Additionally, add a re-entrancy guard to infer_source_expr_assign so that any remaining cycle through an assignment source bails out with Unknown instead of recursing indefinitely.

…p variable (#1)

* fix: stack overflow when a for loop's iterable references its own loop variable

Fixes withered-magic#439.

When collecting scopes, `for` statements declared their loop variables in
the same scope in which the iterable expression had been collected, unlike
assignments and comprehensions which allocate a fresh scope first. As a
result, a name used in the iterable resolved to the loop variable itself.
Inferring the type of the loop variable then required inferring the
iterable, which required inferring the loop variable again, and so on until
the stack overflowed. This is triggered by code such as:

    for idl in idls:
        for idl in idl.idl_files:
            ...

which appears in rules_ros2's ament.bzl and crashed the server whenever that
file was analyzed, e.g. after go-to-definition on `py_exec_launcher`.

The iterable is evaluated before the loop variables are bound, so allocate a
new scope for the targets. Names in the iterable now resolve to the enclosing
definition (or report "not defined" if there is none).

Additionally, add a re-entrancy guard to `infer_source_expr_assign` so that
any remaining cycle through an assignment source bails out with `Unknown`
instead of recursing indefinitely.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWwYHECoSdkTj6bkAdt6xQ

* test: cover for-loop iterable shadowing with code flow analysis enabled

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWwYHECoSdkTj6bkAdt6xQ

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

Stack Overflow using code nagivation

1 participant