Skip to content

fix(compiler): defer variables that read variables needing other files - #551

Merged
paralin merged 1 commit into
s4wave:masterfrom
cogentcore:fix/lazy-var-chain
Oct 28, 2026
Merged

paralin merged 1 commit into
s4wave:masterfrom
cogentcore:fix/lazy-var-chain

Conversation

@rcoreilly

Copy link
Copy Markdown
Contributor

A package variable whose initializer uses a declaration of another file of its package, such as a struct type, is initialized lazily through a getter, since that file may not be evaluated yet. But a variable that only reads such a variable stayed eager, so its initializer called the getter at module evaluation, which ran the lazy initializer early anyway. When the file declaring the class is evaluated after the reader's file, as happens in an import cycle between the files, this throws a ReferenceError (Cannot access 'X' before initialization).

github.com/pkg/sftp has this pattern: sftp.go declares supportedSFTPExtensions as a slice of sshExtensionPair, a type of packet.go, and then sftpExtensions = supportedSFTPExtensions. A program that imports it failed at load time.

lazyPackageVars now makes such readers lazy too, transitively, through markLazyReaders. It only propagates from variables made lazy because their initializers or zero values need other files, so the whole-program handling of deferred tables is unchanged, and it leaves eager the initializers with runtime effects and blank variables, which must still run at package initialization.

The cross_file_struct_typeinfo_zero fixture gains a third file, whose table of a type of b.go is read by another variable, and b.go uses that variable, so b.go is evaluated after it; it failed with the ReferenceError before. The full compiler test suite passes, with no other generated fixture changes.

A package variable whose initializer uses a declaration of another file,
such as a struct type, is initialized lazily, as that file may not be
evaluated yet. A variable that read it was still initialized eagerly, so
reading it ran the lazy initializer early, and threw a ReferenceError when
the other file's class was not declared yet. github.com/pkg/sftp has this:
sftpExtensions = supportedSFTPExtensions, a slice of a type of another file.

Such readers are now lazy too, unless their initializers have runtime
effects, transitively.

Signed-off-by: Randall C. O'Reilly <oreilly@ucdavis.edu>
@paralin
paralin merged commit 3c4a21b into s4wave:master Oct 28, 2026
7 checks passed
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.

2 participants