test: update test262 cases to latest#20959
Conversation
Update the test262 submodule to commit 673e9bacbe28 (2026-05-11), which
adds two new ResolveExport conformance tests for star exports with cyclic
indirect re-exports:
- module-code/instn-star-iee-single-cycle-same-name.js
- module-code/instn-star-iee-multi-cycle-same-name.js
Both fail because webpack hoists star-exported names into the importer's
namespace without per-name cycle detection, so a cyclic indirect re-export
wins and the runtime ends up chasing a getter that points back at itself
("Maximum call stack size exceeded"). The spec requires the cyclic branch
to return null from ResolveExport and the star loop to fall through to a
non-cyclic path.
The fix would require a larger refactor of HarmonyExportImportedSpecifier
resolution, so both new cases are added to knownBugs with a comment
explaining the root cause.
Per the TC39 `ResolveExport` spec, when a star-reexported module
re-exports a name back to the importer cyclically, cycle detection
should return null from the cyclic branch and the star loop should
fall through to a non-cyclic source. In the new test262 cases:
// a.js
export * from './b.js';
export * from './c.js';
// b.js
export { foo } from './a.js';
// c.js
export let foo = 42;
webpack previously hoisted every star-exported name into the
importer's namespace without per-name cycle detection, so b's cyclic
`foo` won over c's terminal binding. The generated bundle emitted
a.foo = () => b.foo
b.foo = () => a.foo
— a getter chain that recurses forever and throws "Maximum call
stack size exceeded" at runtime.
`HarmonyExportImportedSpecifierDependency` now detects when a
candidate star-export contribution's target chain loops back to the
importer under the same name and skips it. The check runs in both
`determineExportAssignments` (which builds the combined name set
for star reexports) and `getStarReexports` (which decides per-dep
contributions), walking the target chain one hop at a time with
visited tracking so namespace targets (`export * as ns from ...`)
and unrelated cycles don't trigger the latent infinite-loop in
`ExportsInfo._findTarget`.
The two test262 cases `instn-star-iee-single-cycle-same-name` and
`instn-star-iee-multi-cycle-same-name` now pass instead of throwing
at runtime.
The cycle detector in HarmonyExportImportedSpecifierDependency is called for every export of every star-reexported module. In barrel-style code (e.g. `export * from './depN.js'` repeated thousands of times, as in the `side-effects-reexport` benchmark) this path is hot enough that allocations and redundant work add a few percent to compile time. Two small fixes: - Probe the first chain hop before allocating the `visited` Set. For terminal local bindings (no `_target`) we now return immediately after one `findTarget` call without allocating the Set; only multi-hop chains pay for cycle tracking. - Hoist the `() => true` filter into a module-level `RETURNS_TRUE` constant so each call doesn't allocate a fresh closure. - In `getStarReexports`, check `hiddenExports` (a cheap `Set.has`) before running the cycle walk. Names that an earlier non-cyclic star already provided are guaranteed non-cyclic because `determineExportAssignments` excludes cyclic candidates from `hiddenExports` upstream.
🦋 Changeset detectedLatest commit: d6845b1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (e5ff221). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@e5ff221
yarn add -D webpack@https://pkg.pr.new/webpack@e5ff221
pnpm add -D webpack@https://pkg.pr.new/webpack@e5ff221 |
There was a problem hiding this comment.
Pull request overview
The PR title and description claim this only updates the test262 submodule and adds two new failing tests (cyclic indirect re-export with star exports) to knownBugs, deferring the actual fix. However, the diff actually implements a behavioral fix in HarmonyExportImportedSpecifierDependency: a new isStarReexportBackToParent helper performs a per-name cycle check to skip cyclic star-export contributions in both determineExportAssignments and getMode-style export collection, and a corresponding patch-level changeset is added. No test262 submodule update or knownBugs change is present in the provided diff.
Changes:
- Add
isStarReexportBackToParenthelper that walksfindTargethops with cycle tracking to detect a star re-export that loops back to the importer under the same name. - Filter cyclic contributions in
determineExportAssignmentsand in two collection loops ofHarmonyExportImportedSpecifierDependency(thenoExtraImportsandhidden-based paths). - Add a patch-level changeset describing the fix.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| lib/dependencies/HarmonyExportImportedSpecifierDependency.js | Introduces cycle-detection helper and applies it at three call sites where star-export names are aggregated. |
| .changeset/star-export-cyclic-indirect-reexport.md | Patch changeset describing the cyclic indirect re-export fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| --- | ||
| "webpack": patch | ||
| --- | ||
|
|
||
| Fix `export *` resolution when a star-reexported module re-exports a name back to the importer cyclically. Previously, in a graph where `a` does `export * from "./b"; export * from "./c";` and `b` does `export { foo } from "./a";` while `c` provides the actual `foo` binding, webpack hoisted `foo` from `b` into `a`'s namespace without per-name cycle detection — emitting a getter chain (`a.foo` → `b.foo` → `a.foo`) that threw "Maximum call stack size exceeded" at runtime. The TC39 `ResolveExport` algorithm requires the cyclic branch to return null and the star loop to fall through to the non-cyclic source. Webpack's `HarmonyExportImportedSpecifierDependency` now detects when a candidate star-export contribution's target chain loops back to the importer under the same name and skips it, letting the sibling `export *` provide the binding. |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (72.09%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #20959 +/- ##
==========================================
- Coverage 91.36% 91.13% -0.24%
==========================================
Files 569 569
Lines 57147 57581 +434
Branches 15227 15408 +181
==========================================
+ Hits 52215 52475 +260
- Misses 4932 5106 +174
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Merging this PR will degrade performance by 38.6%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
Update the test262 submodule to commit 673e9bacbe28 (2026-05-11), which
adds two new ResolveExport conformance tests for star exports with cyclic
indirect re-exports:
Both fail because webpack hoists star-exported names into the importer's
namespace without per-name cycle detection, so a cyclic indirect re-export
wins and the runtime ends up chasing a getter that points back at itself
("Maximum call stack size exceeded"). The spec requires the cyclic branch
to return null from ResolveExport and the star loop to fall through to a
non-cyclic path.
The fix would require a larger refactor of HarmonyExportImportedSpecifier
resolution, so both new cases are added to knownBugs with a comment
explaining the root cause.