Repository navigation
Conversation
A class of an import cycle that code in the other module can reach before the class statement was refused (SC1016). It now gets the initialization flag a module's own early-reached classes already had: references from code that can run earlier check it, so Node's ReferenceError appears only when the class is actually reached early. The reference scan resolves other modules' import bindings. An `extends` clause in another module that can run early keeps the refusal, since a compiled subclass is static. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The references of a cycle class were found by their spelling, so a class
imported under another name (`import { Sink as Alias }`) was never seen as
reached early, and neither was a let or const imported under another
name. An `extends` clause only counted when its expression was the bare
class name. A static method read as a value (`const f = Sink.m`) built a
closure that no check covered.
The early-binding scan and the class reference scan now also match each
file's local import names that resolve to the binding, and record them:
Node's ReferenceError names the binding the access spells, so the check
names the alias. The heritage check walks the whole `extends` expression.
A closure of a flagged class's static method checks the class like a
static call does.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two modules that import each other, where a class in one can be reached from code that runs before the class statement, were refused with SC1016 ("the class … can be accessed before its declaration runs"). The usual case is a class that is only used after both modules finished initializing, which Node runs normally. Node throws a temporal-dead-zone ReferenceError only when the class is actually reached early.
Classes of an import cycle now get the same initialization flag that a module's own early-reached classes already had (
registerClassInitFlag). The class statement sets the flag, and every reference from code that can run earlier (new, the class value,instanceof, static members) checks it first, throwing Node'sReferenceError: Cannot access 'X' before initialization.Two details:
extendsclause in another module that can run before the class statement keeps the refusal. Node evaluates the clause when that module's class statement runs, but a compiled subclass is static and has nothing to check. This is the existingcycle-class-earlydiagnostics fixture, whose output is unchanged.Evidence
6440-cycle-class-late-use/: a logger-style cycle. One module declares a class and builds it from an arrow in a module-level object; the other reaches it only from functions called after initialization. Main already compiled this shape; it is a regression check for the late case.6441-cycle-class-early-access/: the other module constructs the class during its own initialization (Node's ReferenceError, caught and printed), and the class works afterwards. Main refused this program.6442-cycle-class-factory/: construction from a factory in the other module after both settled, withinstanceof. Main also compiled this shape; it pins the late case through a factory.cyclecorpus programs and the diagnostics suite pass unchanged.test:ts7 --baselines-only, and the self-hosting IR build are clean.🤖 Generated with Claude Code