Skip to content

Conversation

@bakkot
Copy link
Member

@bakkot bakkot commented Nov 8, 2025

Fixes #3710. Specifically, this makes it so that the example under "this throws" in this comment no longer throws, matching the behavior for re-exporting bindings rather than full namespaces.

I also added an explanatory comment about why we're doing this rewriting.

cc @nicolo-ribaudo @guybedford

@github-actions
Copy link

github-actions bot commented Nov 8, 2025

The rendered spec for this PR is available at https://tc39.es/ecma262/pr/3715.

@ljharb ljharb added normative change Affects behavior required to correctly evaluate some ECMAScript source text needs consensus This needs committee consensus before it can be eligible to be merged. needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 labels Nov 8, 2025
@nicolo-ribaudo nicolo-ribaudo added has consensus This has committee consensus. and removed needs consensus This needs committee consensus before it can be eligible to be merged. labels Nov 18, 2025
@nicolo-ribaudo nicolo-ribaudo added has test262 tests and removed needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 labels Nov 26, 2025
lando-prod-mozilla bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Nov 26, 2025
…=jonco

This patch implements tc39/ecma262#3715, to make

  import * as ns from "mod";
  export { ns };

behave the same as

  export * as ns from "mod";

Tested by tc39/test262#4606

Differential Revision: https://phabricator.services.mozilla.com/D274013
nicolo-ribaudo added a commit to nicolo-ribaudo/WebKit that referenced this pull request Nov 27, 2025
https://bugs.webkit.org/show_bug.cgi?id=303141

Reviewed by NOBODY (OOPS!).

This patch changes JSC's handling of `import * as ns; export { ns }`
to align with tc39/ecma262#3715, which reached
consensus in the Nov 2025 TC39 meeting.

This will be tested by tc39/test262#4606, for
now I manually verified that the relevant tests in that PR are failing
before this patch and passing after it.

* Source/JavaScriptCore/parser/ModuleAnalyzer.cpp:
(JSC::ModuleAnalyzer::exportVariable):
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Nov 27, 2025
…=jonco

This patch implements tc39/ecma262#3715, to make

  import * as ns from "mod";
  export { ns };

behave the same as

  export * as ns from "mod";

Tested by tc39/test262#4606

Differential Revision: https://phabricator.services.mozilla.com/D274013

UltraBlame original commit: d14a908552e6d040c7538351430b3152a4a36887
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Nov 27, 2025
…=jonco

This patch implements tc39/ecma262#3715, to make

  import * as ns from "mod";
  export { ns };

behave the same as

  export * as ns from "mod";

Tested by tc39/test262#4606

Differential Revision: https://phabricator.services.mozilla.com/D274013

UltraBlame original commit: d14a908552e6d040c7538351430b3152a4a36887
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Nov 27, 2025
…=jonco

This patch implements tc39/ecma262#3715, to make

  import * as ns from "mod";
  export { ns };

behave the same as

  export * as ns from "mod";

Tested by tc39/test262#4606

Differential Revision: https://phabricator.services.mozilla.com/D274013

UltraBlame original commit: d14a908552e6d040c7538351430b3152a4a36887
nicolo-ribaudo added a commit to nicolo-ribaudo/WebKit that referenced this pull request Nov 28, 2025
https://bugs.webkit.org/show_bug.cgi?id=303141

Reviewed by NOBODY (OOPS!).

This patch changes JSC's handling of `import * as ns; export { ns }`
to align with tc39/ecma262#3715, which reached
consensus in the Nov 2025 TC39 meeting.

This will be tested by tc39/test262#4606, for
now I manually verified that the relevant tests in that PR are failing
before this patch and passing after it.

* Source/JavaScriptCore/parser/ModuleAnalyzer.cpp:
(JSC::ModuleAnalyzer::exportVariable):
webkit-commit-queue pushed a commit to nicolo-ribaudo/WebKit that referenced this pull request Dec 5, 2025
https://bugs.webkit.org/show_bug.cgi?id=303141

Reviewed by Yusuke Suzuki and Sosuke Suzuki.

This patch changes JSC's handling of `import * as ns; export { ns }`
to align with tc39/ecma262#3715, which reached
consensus in the Nov 2025 TC39 meeting.

This will be tested by tc39/test262#4606, for
now I manually verified that the relevant tests in that PR are failing
before this patch and passing after it.

* Source/JavaScriptCore/parser/ModuleAnalyzer.cpp:
(JSC::ModuleAnalyzer::exportVariable):

Canonical link: https://commits.webkit.org/303952@main
@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Dec 5, 2025

The change has been implemented in SpiderMonkey and JavaScriptCore.

It has not been implemented in V8 yet, but V8 also did not match the original behavior.

@bakkot
Copy link
Member Author

bakkot commented Dec 5, 2025

Since this is just making an error into a non-error I think that's good enough, no need to wait for them to ship.

juliopiubello pushed a commit to juliopiubello/WebKit that referenced this pull request Dec 18, 2025
https://bugs.webkit.org/show_bug.cgi?id=303141

Reviewed by Yusuke Suzuki and Sosuke Suzuki.

This patch changes JSC's handling of `import * as ns; export { ns }`
to align with tc39/ecma262#3715, which reached
consensus in the Nov 2025 TC39 meeting.

This will be tested by tc39/test262#4606, for
now I manually verified that the relevant tests in that PR are failing
before this patch and passing after it.

* Source/JavaScriptCore/parser/ModuleAnalyzer.cpp:
(JSC::ModuleAnalyzer::exportVariable):

Canonical link: https://commits.webkit.org/303952@main
@bakkot bakkot added editor call to be discussed in the next editor call and removed editor call to be discussed in the next editor call labels Dec 29, 2025
@bakkot
Copy link
Member Author

bakkot commented Dec 29, 2025

V8 issue (at least according to test262.status): https://issues.chromium.org/issues/464065358

@michaelficarra wants to hold off for a couple months to see if V8 runs into any difficulties, but if they haven't landed by the time we cut the next yearly edition we'll include this either way.

@o-
Copy link

o- commented Jan 7, 2026

This is a bigger change on our end since apparently we never treated "export * as x" as proper re-exports. Hence the current behavior where you could not require such a namespace through multiple paths. I think there is a non-zero chance that we will run into problems.

@iamstolis
Copy link

If I understand correctly then this change modifies the behavior of deferred imports. If the re-exported namespace object was imported using a deferred import then the result was a deferred namespace object i.e. you got the deferred namespace object from the re-export. If you replace these 2 steps by a direct re-export then you get a regular namespace object (because there is nothing like a deferred export). Am I missing something or is this expected?

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 14, 2026

@iamstolis The import defer proposal would be updated to generate a binding that directly points to the [[DeferredNamespace]] slot when doing import defer+export{}, similarly to what this PR effectively does for non-deferred imports.

DevCheckOG pushed a commit to DevCheckOG/v8 that referenced this pull request Jan 21, 2026
This fixes a long standing issue where re-exported namespaces are not
disambiguated. If a namespace is re-exported in multiple dependencies,
then according to ecma262 this is not an ambiguous import.

Example:

                    export let x = 1
                        /       \
    export * as dep from ...    export * as dep from ...
                       \        /
                   export * from left
                   export * from right
                           |
                 import { dep } from ...
                 haz(dep.x)

While doing so we also implement the normative PR3715 [0] treating
`export * as dep from ...` the same as
`import * as dep from ...; export { dep }`.

Since modules can import themselves we must be able to produce a
shared binding cell to identify the namespace, before the namespace is
fully populated. To that end we store the namespace indirectly through
an additional binding cell in the module that we can use as a result
of the name resolution.

In other words in a module graph like

       export let x = 1
          |
       export * as dep from ...
          |
       import { dep } from ...

We will now resolve `{ dep }` to the special namespace binding cell on
the topmost module instead of the private re-export binding cell of the
middle module.

[0] tc39/ecma262#3715

Bug: 464065358
Change-Id: Ief31089987085772f92f3c32aecbf02db6796cee
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7362765
Auto-Submit: Olivier Flückiger <[email protected]>
Commit-Queue: Leszek Swirski <[email protected]>
Reviewed-by: Leszek Swirski <[email protected]>
Cr-Commit-Position: refs/heads/main@{#104825}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

has consensus This has committee consensus. has test262 tests normative change Affects behavior required to correctly evaluate some ECMAScript source text

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Weird handling of import * as ns from "..."; export { ns }

8 participants