Skip to content

Fix spurious 'can't reuse name' errors when a multi-file package has a syntax error#5147

Open
pmetras wants to merge 6 commits intoponylang:mainfrom
pmetras:issue-4160/spurious-error-message-generation
Open

Fix spurious 'can't reuse name' errors when a multi-file package has a syntax error#5147
pmetras wants to merge 6 commits intoponylang:mainfrom
pmetras:issue-4160/spurious-error-message-generation

Conversation

@pmetras
Copy link
Copy Markdown

@pmetras pmetras commented Apr 7, 2026

Fix the problem demonstrated into issue #4160: getting extra error messages in situations where one .pony files of an included (used) module has a syntax error and another of the module files that the main code is importing has multiple for loops using the same loop variable.

The issue was caused by the compiler's package loading logic. When a package containing multiple files was loaded, if one file had a syntax error, the package was left in a partially-processed state. Subsequent attempts to use or "catch up" that package to the current compiler pass would re-run passes (like the scope pass) on the existing AST. Since the scope pass had already partially populated the symbol tables, re-running it caused it to encounter its own previously defined symbols and report them as illegal name reuses.

The fix is to set AST_FLAG_PRESERVE on the package when parse_files_in_dir fails (same pattern already used when ast_passes_subtree fails). This stops future passes from visiting the broken package.
The magic->mapped_path branch also needed the same guard, because add_package_path uses it and parse_files_in_dir has the same partial-parse behavior in both branches.

Added BadPonyTest.SpuriousErrorMessageGeneration test with the new add_package_path utility method to be able to test on multi-files packages.

@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Apr 7, 2026
@SeanTAllen SeanTAllen added the changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge label Apr 7, 2026
@SeanTAllen SeanTAllen self-requested a review April 7, 2026 00:43
@ponylang-main
Copy link
Copy Markdown
Contributor

Hi @pmetras,

The changelog - fixed label was added to this pull request; all PRs with a changelog label need to have release notes included as part of the PR. If you haven't added release notes already, please do.

Release notes are added by creating a uniquely named file in the .release-notes directory. We suggest you call the file 5147.md to match the number of this pull request.

The basic format of the release notes (using markdown) should be:

## Title

End user description of changes, why it's important,
problems it solves etc.

If a breaking change, make sure to include 1 or more
examples what code would look like prior to this change
and how to update it to work after this change.

Thanks.

// partially-initialised package. Without this, passes that run on the
// whole program tree (e.g. the scope pass) would visit modules that
// were successfully parsed in this package but whose for-loop sugar
// has not been applied, producing spurious errors in those files.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The comment here ties the explanation to for-loop sugar, but the underlying problem is more general. Any pass running on a partially-processed package could produce spurious errors. The for-loop case is just how this manifested in #4160. I'd drop the for-loop detail and keep it general — "producing spurious errors in those files" is enough. The for-loop specifics are better suited to the commit message where they're tied to the issue report.

} else if(magic->mapped_path != NULL) {
if(!parse_files_in_dir(package, magic->mapped_path, opt))
{
ast_setflag(package, AST_FLAG_PRESERVE);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could use a brief comment here. Even just a pointer to the comment on the other branch below so someone reading this code path doesn't have to go hunting for why the flag is being set.

@SeanTAllen SeanTAllen changed the title Broken multi-files package reports incorrect name reuses Fix spurious 'can't reuse name' errors when a multi-file package has a syntax error Apr 7, 2026
Comment on lines +3 to +8
Fix [issue 4160](https://github.com/ponylang/ponyc/issues/4160) that contains
and example reproducing the problem.
When a package `use`d another package containing multiple `.pony` files, and
one of these files had a syntax error, the compiler output wrong and extra
error messages, particularly when the first code had multiple `for` loops
using the same loop variable.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

paragraphs in release notes shouldn't have linebreaks. they should flow to fit the space they are in,

@SeanTAllen
Copy link
Copy Markdown
Member

The release notes in this PR contain implementation details that aren't relevant to users. Here's a suggested replacement:

## Fix spurious 'can't reuse name' errors when a multi-file package has a syntax error

When a package contained multiple `.pony` files and one of them had a syntax error, the compiler would produce spurious `can't reuse name` errors for unrelated valid code in the other files. This was most visible when a valid file reused a loop variable name across consecutive `for` loops — a perfectly legal pattern that the compiler would incorrectly flag.

The spurious errors no longer appear. You'll still see the real syntax error, but the compiler won't pile on with bogus errors from other files in the same package.

Comment on lines +3 to +7
When a package contained multiple `.pony` files and one of them had a syntax
error, the compiler would produce spurious `can't reuse name` errors for
unrelated valid code in the other files. This was most visible when a valid
file reused a loop variable name across consecutive `for` loops — a perfectly
legal pattern that the compiler would incorrectly flag.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please remove the hard wrapping in this file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we don't do any line breaks in release notes except for paragraphs so they can flow to the viewport in the various places they are displayed.

// reuse a loop variable name across consecutive for loops.
// The fixture package has two files: bad.pony (parse error) comes before
// good.pony (valid, with consecutive "for i" loops) alphabetically.
add_package_path("pkg", PONY_TEST_LIBPONYC_DIR "/fixtures/spurious-error-message-generation");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

im not a fan of adding fixtures to a testing style we are trying to move away from. @jemc what are your thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge discuss during sync Should be discussed during an upcoming sync

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants