Skip to content

Commit d7e39ff

Browse files
committed
Sema: Reexport SPI via Swift exported imports but not clang exported imports
This is a new attempt at a reexport feature for SPI decls. The previous behavior was to reexport SPIs only between modules with both `@_exported` and an export-as relationship. The limitation on export-as turned out to be too restrictive in some cases. We may be tempted to reexport SPIs through all exported imports. However, the exported imports are very common between clang module and it can lead to surprises if dependencies between clang modules end up exporting SPIs from unexpected modules. As a middle ground, reexport SPI only through Swift `@_exported` dependencies, and not through clang reexports. While this is a new distinction between Swift and clang dependencies, I believe it provides the expected behavior and the result is more straightforward than the current logic. rdar://115901208
1 parent 94cd52c commit d7e39ff

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

lib/AST/Module.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,8 +3386,8 @@ void SourceFile::lookupImportedSPIGroups(
33863386
for (auto &import : *Imports) {
33873387
if (import.options.contains(ImportFlags::SPIAccessControl) &&
33883388
(importedModule == import.module.importedModule ||
3389-
(imports.isImportedBy(importedModule, import.module.importedModule) &&
3390-
importedModule->isExportedAs(import.module.importedModule)))) {
3389+
imports.isImportedByViaSwiftOnly(importedModule,
3390+
import.module.importedModule))) {
33913391
spiGroups.insert(import.spiGroups.begin(), import.spiGroups.end());
33923392
}
33933393
}

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,8 @@ void SerializedASTFile::lookupImportedSPIGroups(
16781678

16791679
if (dep.Import->importedModule == importedModule ||
16801680
(imports.isImportedBy(importedModule, dep.Import->importedModule) &&
1681-
importedModule->isExportedAs(dep.Import->importedModule))) {
1681+
imports.isImportedByViaSwiftOnly(importedModule,
1682+
dep.Import->importedModule))) {
16821683
spiGroups.insert(dep.spiGroups.begin(), dep.spiGroups.end());
16831684
}
16841685
}

test/SPI/reexported-spi-groups.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
// RUN: %t/Client_FileA.swift %t/Client_FileB.swift\
5656
// RUN: -swift-version 5 -I %t -verify
5757

58-
/// Test that SPIs aren't avaible from a reexport without export_as
58+
/// SPIs are now reexported by any `@_exported` from Swift modules, no matter
59+
/// if `export_as` is present or not.
5960
// RUN: %target-swift-frontend -typecheck \
6061
// RUN: %t/NonExportedAsClient.swift \
6162
// RUN: -swift-version 5 -I %t -verify
@@ -92,6 +93,8 @@ public func exportedPublicFunc() {}
9293

9394
@_spi(X) public struct ExportedSpiType {}
9495

96+
@_spi(O) public func exportedSpiFuncOtherGroup() {}
97+
9598
//--- Exporter.swift
9699

97100
@_exported import Exported
@@ -130,6 +133,7 @@ public func clientA() {
130133
exportedPublicFunc()
131134
exportedSpiFunc()
132135
exporterSpiFunc()
136+
exportedSpiFuncOtherGroup() // expected-error {{cannot find 'exportedSpiFuncOtherGroup' in scope}}
133137
}
134138

135139
@inlinable
@@ -159,7 +163,7 @@ public func clientB() {
159163

160164
public func client() {
161165
exportedPublicFunc()
162-
exportedSpiFunc() // expected-error {{cannot find 'exportedSpiFunc' in scope}}
166+
exportedSpiFunc()
163167
exporterSpiFunc()
164168
}
165169

0 commit comments

Comments
 (0)