mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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
This commit is contained in:
@@ -3386,8 +3386,8 @@ void SourceFile::lookupImportedSPIGroups(
|
|||||||
for (auto &import : *Imports) {
|
for (auto &import : *Imports) {
|
||||||
if (import.options.contains(ImportFlags::SPIAccessControl) &&
|
if (import.options.contains(ImportFlags::SPIAccessControl) &&
|
||||||
(importedModule == import.module.importedModule ||
|
(importedModule == import.module.importedModule ||
|
||||||
(imports.isImportedBy(importedModule, import.module.importedModule) &&
|
imports.isImportedByViaSwiftOnly(importedModule,
|
||||||
importedModule->isExportedAs(import.module.importedModule)))) {
|
import.module.importedModule))) {
|
||||||
spiGroups.insert(import.spiGroups.begin(), import.spiGroups.end());
|
spiGroups.insert(import.spiGroups.begin(), import.spiGroups.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1678,7 +1678,8 @@ void SerializedASTFile::lookupImportedSPIGroups(
|
|||||||
|
|
||||||
if (dep.Import->importedModule == importedModule ||
|
if (dep.Import->importedModule == importedModule ||
|
||||||
(imports.isImportedBy(importedModule, dep.Import->importedModule) &&
|
(imports.isImportedBy(importedModule, dep.Import->importedModule) &&
|
||||||
importedModule->isExportedAs(dep.Import->importedModule))) {
|
imports.isImportedByViaSwiftOnly(importedModule,
|
||||||
|
dep.Import->importedModule))) {
|
||||||
spiGroups.insert(dep.spiGroups.begin(), dep.spiGroups.end());
|
spiGroups.insert(dep.spiGroups.begin(), dep.spiGroups.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,8 @@
|
|||||||
// RUN: %t/Client_FileA.swift %t/Client_FileB.swift\
|
// RUN: %t/Client_FileA.swift %t/Client_FileB.swift\
|
||||||
// RUN: -swift-version 5 -I %t -verify
|
// RUN: -swift-version 5 -I %t -verify
|
||||||
|
|
||||||
/// Test that SPIs aren't avaible from a reexport without export_as
|
/// SPIs are now reexported by any `@_exported` from Swift modules, no matter
|
||||||
|
/// if `export_as` is present or not.
|
||||||
// RUN: %target-swift-frontend -typecheck \
|
// RUN: %target-swift-frontend -typecheck \
|
||||||
// RUN: %t/NonExportedAsClient.swift \
|
// RUN: %t/NonExportedAsClient.swift \
|
||||||
// RUN: -swift-version 5 -I %t -verify
|
// RUN: -swift-version 5 -I %t -verify
|
||||||
@@ -92,6 +93,8 @@ public func exportedPublicFunc() {}
|
|||||||
|
|
||||||
@_spi(X) public struct ExportedSpiType {}
|
@_spi(X) public struct ExportedSpiType {}
|
||||||
|
|
||||||
|
@_spi(O) public func exportedSpiFuncOtherGroup() {}
|
||||||
|
|
||||||
//--- Exporter.swift
|
//--- Exporter.swift
|
||||||
|
|
||||||
@_exported import Exported
|
@_exported import Exported
|
||||||
@@ -130,6 +133,7 @@ public func clientA() {
|
|||||||
exportedPublicFunc()
|
exportedPublicFunc()
|
||||||
exportedSpiFunc()
|
exportedSpiFunc()
|
||||||
exporterSpiFunc()
|
exporterSpiFunc()
|
||||||
|
exportedSpiFuncOtherGroup() // expected-error {{cannot find 'exportedSpiFuncOtherGroup' in scope}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
@@ -159,7 +163,7 @@ public func clientB() {
|
|||||||
|
|
||||||
public func client() {
|
public func client() {
|
||||||
exportedPublicFunc()
|
exportedPublicFunc()
|
||||||
exportedSpiFunc() // expected-error {{cannot find 'exportedSpiFunc' in scope}}
|
exportedSpiFunc()
|
||||||
exporterSpiFunc()
|
exporterSpiFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user