ModuleInterface: Print imports with @preconcurrency in swiftinterface files.

When a module has been imported `@preconcurrency` in source, when it is printed
in a `swiftinterface` file it should be printed along with the attribute to
ensure that type checking of the module's public declarations behaves
consistently.

This fix is a little unsatisfying because it adds another a linear scan over
all imports in the source for each printed import. This should be improved, but
it can be done later.

Resolves rdar://136857313.
This commit is contained in:
Allan Shortlidge
2025-09-15 17:05:12 -07:00
parent 01873c996f
commit 4841bcffa1
8 changed files with 98 additions and 0 deletions

View File

@@ -1044,6 +1044,20 @@ void ModuleDecl::lookupImportedSPIGroups(
FORWARD(lookupImportedSPIGroups, (importedModule, spiGroups));
}
bool ModuleDecl::isModuleImportedPreconcurrency(
const ModuleDecl *importedModule) const {
for (const FileUnit *file : getFiles()) {
if (file->isModuleImportedPreconcurrency(importedModule))
return true;
if (auto *synth = file->getSynthesizedFile()) {
if (synth->isModuleImportedPreconcurrency(importedModule))
return true;
}
}
return false;
}
void ModuleDecl::lookupAvailabilityDomains(
Identifier identifier,
llvm::SmallVectorImpl<AvailabilityDomain> &results) const {
@@ -3050,6 +3064,20 @@ void SourceFile::lookupImportedSPIGroups(
}
}
bool SourceFile::isModuleImportedPreconcurrency(
const ModuleDecl *importedModule) const {
auto &imports = getASTContext().getImportCache();
for (auto &import : *Imports) {
if (import.options.contains(ImportFlags::Preconcurrency) &&
(importedModule == import.module.importedModule ||
imports.isImportedByViaSwiftOnly(importedModule,
import.module.importedModule))) {
return true;
}
}
return false;
}
bool shouldImplicitImportAsSPI(ArrayRef<Identifier> spiGroups) {
for (auto group : spiGroups) {
if (group.empty())