Skip to content

Commit d9d0b2e

Browse files
committed
[Sema] Make extension binding lazy for SourceLoader
This will mainly be useful once extension binding is fully requestified, but even now it's a good idea to ensure module loading isn't kicking name lookup.
1 parent 92f2aca commit d9d0b2e

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

include/swift/Sema/SourceLoader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ModuleDecl;
2424
class SourceLoader : public ModuleLoader {
2525
private:
2626
ASTContext &Ctx;
27+
std::vector<ModuleDecl *> ModulesToBindExtensions;
2728
bool EnableLibraryEvolution;
2829

2930
explicit SourceLoader(ASTContext &ctx,

lib/Sema/SourceLoader.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,20 @@ ModuleDecl *SourceLoader::loadModule(SourceLoc importLoc,
142142
if (EnableLibraryEvolution)
143143
importMod->setResilienceStrategy(ResilienceStrategy::Resilient);
144144
Ctx.addLoadedModule(importMod);
145+
Ctx.bumpGeneration();
146+
ModulesToBindExtensions.push_back(importMod);
145147

146148
performImportResolution(importMod);
147-
bindExtensions(*importMod);
148149
return importMod;
149150
}
150151

151152
void SourceLoader::loadExtensions(NominalTypeDecl *nominal,
152153
unsigned previousGeneration) {
153-
// Type-checking the source automatically loads all extensions; there's
154-
// nothing to do here.
154+
// Given we do full extension binding per module, there's no benefit to
155+
// tracking generations, we just bind extensions for any modules we haven't
156+
// yet bound. We take the vector before iterating to avoid reentrancy.
157+
std::vector<ModuleDecl *> modulesToBind;
158+
std::swap(ModulesToBindExtensions, modulesToBind);
159+
for (auto *M : modulesToBind)
160+
bindExtensions(*M);
155161
}

0 commit comments

Comments
 (0)