Skip to content

[MemberLoading] Split storage and non-storage member loading#87065

Merged
j-hui merged 3 commits intoswiftlang:mainfrom
j-hui:load-storage-members
Feb 10, 2026
Merged

[MemberLoading] Split storage and non-storage member loading#87065
j-hui merged 3 commits intoswiftlang:mainfrom
j-hui:load-storage-members

Conversation

@j-hui
Copy link
Contributor

@j-hui j-hui commented Feb 7, 2026

getStoredProperties() shouldn't call getMembers(), because can have the side effect of un-lazily loading everything. Instead, only ensure that storage-relevant members are loaded and iterate through those.

This patch set builds on #87026 (which merged separately) to avoid the import order from catastrophically messing up every single module interface test (which happened anyway; see the mongo diff there).

This patch set is necessary for the lazy importing work in #87016.

rdar://156949141

Restructure this function into a state-holding class with a recursive
method, to make it easier to thread state around.
@j-hui
Copy link
Contributor Author

j-hui commented Feb 7, 2026

@swift-ci please test

@j-hui
Copy link
Contributor Author

j-hui commented Feb 8, 2026

Please ignore the changes in lib/AST/ASTPrinter.cpp and most of the test changes when reviewing this. The only test changes are:

  • test/Interop/Cxx/class/linked-records-module-interface.swift
  • test/Interop/Cxx/namespace/templates-with-forward-decl-module-interface.swift

where I had to reorder a couple of members.

(These ASTPrinter-related changes should disappear from the diff when #87026 / 9dc1174 lands)

Doing so allows further granularity when lazily loading members.
@j-hui j-hui force-pushed the load-storage-members branch from 7a4c932 to 155b794 Compare February 8, 2026 01:17
@j-hui
Copy link
Contributor Author

j-hui commented Feb 8, 2026

@swift-ci please test

@j-hui j-hui force-pushed the load-storage-members branch from 155b794 to f765ff4 Compare February 8, 2026 08:07
@j-hui
Copy link
Contributor Author

j-hui commented Feb 8, 2026

@swift-ci please test

visitMember(actorSystemVar);
for (auto *member : implDecl->getMembers())
implDecl->loadStorageMembers();
for (auto *member : implDecl->getCurrentMembersWithoutLoading())
Copy link
Contributor

Choose a reason for hiding this comment

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

Should enumerateStoredPropertiesAndMissing() be unified with computeLoweredProperties() in some way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh sure! I could do that if you think it'll benefit the code organization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok so I took a crack at this. I think it's certainly possible to unify enumerateStoredPropertiesAndMissing() and InitializablePropertiesRequest::evaluate(), and perhaps computeLoweredProperties().

However, I'm a bit hesitant to land such a change in this patch. For one thing, I wanted to keep this diff small and focused on the functional change, which is the removal of getMembers().

The other thing is that there are slight discrepancies between these functions. For instance, InitializablePropertiesRequest::evaluate() directly iterates through the members of decl, whereas the others iterate through decl's implementation context. There's also that knownStoredProperties set that prevents enumerateStoredPropertiesAndMissing() from visiting members more than once. I think these differences should be inconsequential, but I'm not confident and I don't know how best to validate this without spending some more time reading code.

Would it be alright if I punt this unification to a follow-up PR?

};

for (auto *member : decl->getMembers())
decl->loadStorageMembers();
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like another spot where we duplicate visiting stored properties and dealing with property wrappers and so on.


for (auto *existingMember : getMembers()) {
addParsedMembers();
for (auto *existingMember : getCurrentMembersWithoutLoading()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like addMemberPreservingSourceOrder() is only called in one place in the parser, can we assert here that getParentSourceFile() != nullptr? Or is it necessary to change this function at all? getMembers() should be the same as getParsedMembers() in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't realize this was only called by the parser, specifically for IDE-related tasks. Using the tests from #87016, I confirmed that this doesn't seem to affect the importedd Clang decls case I'm ultimately interested in.

I'm happy to back out of this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(And am happy to make this change in a follow-up if it makes sense.)

getStoredProperties() shouldn't call getMembers(), because can have
the side effect of un-lazily loading everything. Instead, only ensure
that storage-relevant members are loaded and iterate through those.
@j-hui j-hui force-pushed the load-storage-members branch from f765ff4 to 3b4a298 Compare February 9, 2026 07:50
@j-hui
Copy link
Contributor Author

j-hui commented Feb 9, 2026

@swift-ci please test

@j-hui j-hui requested a review from slavapestov February 9, 2026 07:51
@j-hui
Copy link
Contributor Author

j-hui commented Feb 9, 2026


Flaky Tests (1):
  Swift(windows-x86_64) :: Constraints/warn_long_compile.swift

Hmm, I don't think this is related to this.

@j-hui
Copy link
Contributor Author

j-hui commented Feb 9, 2026

@swift-ci please test windows platform

1 similar comment
@j-hui
Copy link
Contributor Author

j-hui commented Feb 9, 2026

@swift-ci please test windows platform

Copy link
Contributor

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

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

Overall looks great, thanks!

/*lazyLoader=*/nullptr);
contextInfo->loader->loadAllMembers(const_cast<Decl *>(container),
contextInfo->memberData);
if (FirstDeclAndLazyMembers.getInt() == LazyMemberStatus::AllLoaded)
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to move this check to the very front?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Behaviorally speaking, doing so shouldn't make a difference to whether we call loadStorageMembers(), so the only impact would be whether this would have the side effect of adding parsed members when AddedParsedMembers is false. Originally, calling getMembers() would always have that side effect, and what I am doing here is preserving that behavior.

Unfortunately at this time I don't know enough about the scenarios where AddedParsedMembers is false to determine when it is safe to not call it, so I'd prefer to defer that to a follow-up PR.

@j-hui j-hui merged commit 03530d6 into swiftlang:main Feb 10, 2026
6 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.

3 participants