[Serialization] Load non-public transitive dependencies on @testable imports

A @testable import allows a client to call internal decls which may
refer to non-public dependencies. To support such a use case, load
non-public transitive dependencies of a module when it's imported
@testable from the main module.

This replaces the previous behavior where we loaded those dependencies
for any modules built for testing. This was risky as we would load more
module for any debug build, opening the door to a different behavior
between debug and release builds. In contrast, applying this logic to
@testable clients will only change the behavior of test targets.

rdar://107329303
This commit is contained in:
Alexis Laferrière
2023-03-28 12:12:36 -07:00
parent 87431a7a66
commit f7f69c6ae1
9 changed files with 72 additions and 13 deletions

View File

@@ -133,6 +133,9 @@ ModuleFile::loadDependenciesForFileContext(const FileUnit *file,
bool missingDependency = false;
for (auto &dependency : Dependencies) {
if (forTestable && dependency.isLoaded())
continue;
assert(!dependency.isLoaded() && "already loaded?");
if (dependency.isHeader()) {
@@ -156,7 +159,7 @@ ModuleFile::loadDependenciesForFileContext(const FileUnit *file,
}
ModuleLoadingBehavior transitiveBehavior =
getTransitiveLoadingBehavior(dependency);
getTransitiveLoadingBehavior(dependency, forTestable);
if (ctx.LangOpts.EnableModuleLoadingRemarks) {
ctx.Diags.diagnose(diagLoc,
@@ -282,7 +285,8 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
}
ModuleLoadingBehavior
ModuleFile::getTransitiveLoadingBehavior(const Dependency &dependency) const {
ModuleFile::getTransitiveLoadingBehavior(const Dependency &dependency,
bool forTestable) const {
ASTContext &ctx = getContext();
ModuleDecl *mod = FileContext->getParentModule();
@@ -293,7 +297,8 @@ ModuleFile::getTransitiveLoadingBehavior(const Dependency &dependency) const {
return Core->getTransitiveLoadingBehavior(dependency.Core,
ctx.LangOpts.DebuggerSupport,
isPartialModule,
ctx.LangOpts.PackageName);
ctx.LangOpts.PackageName,
forTestable);
}
bool ModuleFile::mayHaveDiagnosticsPointingAtBuffer() const {