Skip to content

Commit 01d458b

Browse files
authored
Merge pull request #84311 from tshortli/preconcurrency-import-in-swiftinterface
ModuleInterface: Print imports with @preconcurrency in swiftinterface files
2 parents 04ff59b + 4841bcf commit 01d458b

File tree

8 files changed

+98
-0
lines changed

8 files changed

+98
-0
lines changed

include/swift/AST/FileUnit.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
126126
const ModuleDecl *importedModule,
127127
llvm::SmallSetVector<Identifier, 4> &spiGroups) const {};
128128

129+
/// Returns true if any import of \p importedModule has the `@preconcurrency`
130+
/// attribute.
131+
virtual bool
132+
isModuleImportedPreconcurrency(const ModuleDecl *importedModule) const {
133+
return false;
134+
};
135+
129136
/// Find all availability domains defined in this module with the given
130137
/// identifier.
131138
///

include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,10 @@ class ModuleDecl
965965
const ModuleDecl *importedModule,
966966
llvm::SmallSetVector<Identifier, 4> &spiGroups) const;
967967

968+
/// Returns true if any import of \p importedModule has the `@preconcurrency`
969+
/// attribute.
970+
bool isModuleImportedPreconcurrency(const ModuleDecl *importedModule) const;
971+
968972
/// Finds the custom availability domain defined by this module with the
969973
/// given identifier and if one exists adds it to results.
970974
void

include/swift/AST/SourceFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,11 @@ class SourceFile final : public FileUnit {
471471
const ModuleDecl *importedModule,
472472
llvm::SmallSetVector<Identifier, 4> &spiGroups) const override;
473473

474+
/// Returns true if any import of \p importedModule has the `@preconcurrency`
475+
/// attribute.
476+
virtual bool isModuleImportedPreconcurrency(
477+
const ModuleDecl *importedModule) const override;
478+
474479
// Is \p targetDecl accessible as an explicitly imported SPI from this file?
475480
bool isImportedAsSPI(const ValueDecl *targetDecl) const;
476481

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ class SerializedASTFile final : public LoadedFile {
466466
const ModuleDecl *importedModule,
467467
llvm::SmallSetVector<Identifier, 4> &spiGroups) const override;
468468

469+
virtual bool isModuleImportedPreconcurrency(
470+
const ModuleDecl *importedModule) const override;
471+
469472
std::optional<CommentInfo> getCommentForDecl(const Decl *D) const override;
470473

471474
bool hasLoadedSwiftDoc() const override;

lib/AST/Module.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,20 @@ void ModuleDecl::lookupImportedSPIGroups(
10441044
FORWARD(lookupImportedSPIGroups, (importedModule, spiGroups));
10451045
}
10461046

1047+
bool ModuleDecl::isModuleImportedPreconcurrency(
1048+
const ModuleDecl *importedModule) const {
1049+
for (const FileUnit *file : getFiles()) {
1050+
if (file->isModuleImportedPreconcurrency(importedModule))
1051+
return true;
1052+
1053+
if (auto *synth = file->getSynthesizedFile()) {
1054+
if (synth->isModuleImportedPreconcurrency(importedModule))
1055+
return true;
1056+
}
1057+
}
1058+
return false;
1059+
}
1060+
10471061
void ModuleDecl::lookupAvailabilityDomains(
10481062
Identifier identifier,
10491063
llvm::SmallVectorImpl<AvailabilityDomain> &results) const {
@@ -3050,6 +3064,20 @@ void SourceFile::lookupImportedSPIGroups(
30503064
}
30513065
}
30523066

3067+
bool SourceFile::isModuleImportedPreconcurrency(
3068+
const ModuleDecl *importedModule) const {
3069+
auto &imports = getASTContext().getImportCache();
3070+
for (auto &import : *Imports) {
3071+
if (import.options.contains(ImportFlags::Preconcurrency) &&
3072+
(importedModule == import.module.importedModule ||
3073+
imports.isImportedByViaSwiftOnly(importedModule,
3074+
import.module.importedModule))) {
3075+
return true;
3076+
}
3077+
}
3078+
return false;
3079+
}
3080+
30533081
bool shouldImplicitImportAsSPI(ArrayRef<Identifier> spiGroups) {
30543082
for (auto group : spiGroups) {
30553083
if (group.empty())

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ static void printImports(raw_ostream &out,
271271
ModuleDecl::ImportFilterKind::Default,
272272
ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay};
273273

274+
// FIXME: Scan over all imports in the module once to build up the attribute
275+
// set for printed imports, instead of repeatedly doing linear scans for each
276+
// kind of attribute.
274277
using ImportSet = llvm::SmallSet<ImportedModule, 8, ImportedModule::Order>;
275278
auto getImports = [M](ModuleDecl::ImportFilter filter) -> ImportSet {
276279
SmallVector<ImportedModule, 8> matchingImports;
@@ -355,6 +358,9 @@ static void printImports(raw_ostream &out,
355358
out << "@_spi(" << spiName << ") ";
356359
}
357360

361+
if (M->isModuleImportedPreconcurrency(importedModule))
362+
out << "@preconcurrency ";
363+
358364
if (Opts.printPackageInterface() &&
359365
!publicImportSet.count(import) &&
360366
packageOnlyImportSet.count(import))

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,14 @@ void SerializedASTFile::lookupImportedSPIGroups(
19151915
}
19161916
}
19171917

1918+
bool SerializedASTFile::isModuleImportedPreconcurrency(
1919+
const ModuleDecl *importedModule) const {
1920+
// This method should only be queried during `-merge-modules` jobs, which are
1921+
// deprecated, and thus no effort has been made to answer this query correctly
1922+
// (@preconcurrency is not encoded on imports in serialized modules).
1923+
return false;
1924+
}
1925+
19181926
std::optional<CommentInfo>
19191927
SerializedASTFile::getCommentForDecl(const Decl *D) const {
19201928
return File.getCommentForDecl(D);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -emit-module %t/PreconcurrencyLib.swift -module-name PreconcurrencyLib -swift-version 5 -enable-library-evolution -emit-module-path %t/PreconcurrencyLib.swiftmodule -emit-module-interface-path %t/PreconcurrencyLib.swiftinterface
5+
// RUN: %target-swift-frontend -emit-module %t/OtherLib.swift -module-name OtherLib -swift-version 5 -enable-library-evolution -emit-module-path %t/OtherLib.swiftmodule -emit-module-interface-path %t/OtherLib.swiftinterface
6+
7+
// RUN: %target-swift-emit-module-interface(%t/ClientLib.swiftinterface) -swift-version 6 %t/ClientLib_file1.swift %t/ClientLib_file2.swift -module-name ClientLib -I %t
8+
// RUN: %target-swift-typecheck-module-from-interface(%t/ClientLib.swiftinterface) -module-name ClientLib -I %t
9+
// RUN: %FileCheck %s < %t/ClientLib.swiftinterface
10+
11+
// CHECK: {{^}}@preconcurrency import OtherLib
12+
// CHECK: {{^}}@preconcurrency import PreconcurrencyLib
13+
// CHECK: public struct Struct1 : Swift.Sendable
14+
// CHECK: public struct Struct2
15+
16+
//--- PreconcurrencyLib.swift
17+
18+
public class C {}
19+
20+
//--- OtherLib.swift
21+
// Intentionally empty
22+
23+
//--- ClientLib_file1.swift
24+
25+
@preconcurrency public import PreconcurrencyLib
26+
public import OtherLib
27+
28+
public struct Struct1: Sendable {
29+
public var c: C
30+
}
31+
32+
//--- ClientLib_file2.swift
33+
34+
internal import PreconcurrencyLib
35+
@preconcurrency internal import OtherLib
36+
37+
public struct Struct2 {}

0 commit comments

Comments
 (0)