Skip to content

Commit 3c77075

Browse files
authored
Merge pull request #60918 from xymus/spi-only-attr
[Sema] Intro the @_spiOnly attribute on import statements
2 parents 77502b5 + a530e38 commit 3c77075

File tree

14 files changed

+87
-3
lines changed

14 files changed

+87
-3
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,13 @@ This prevents types from that module being exposed in API
451451
(types of public functions, constraints in public extension etc.)
452452
and ABI (usage in `@inlinable` code).
453453

454+
## `@_spiOnly`
455+
456+
Marks an import to be used in SPI and implementation details only.
457+
The import statement will be printed in the private swiftinterface only and
458+
skipped in the public swiftinterface. Any use of imported types and decls in API
459+
will be diagnosed.
460+
454461
## `@_implements(ProtocolName, Requirement)`
455462

456463
An attribute that indicates that a function with one name satisfies

include/swift/AST/Attr.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,11 @@ SIMPLE_DECL_ATTR(typeWrapper, TypeWrapper,
768768
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
769769
134)
770770

771+
SIMPLE_DECL_ATTR(_spiOnly, SPIOnly,
772+
OnImport | UserInaccessible |
773+
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
774+
135)
775+
771776
// If you're adding a new underscored attribute here, please document it in
772777
// docs/ReferenceGuides/UnderscoredAttributes.md.
773778

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,9 @@ WARNING(spi_attribute_on_import_of_public_module,none,
19021902
"'@_spi' import of %0 will not include any SPI symbols; "
19031903
"%0 was built from the public interface at %1",
19041904
(DeclName, StringRef))
1905+
ERROR(spi_only_imports_not_enabled, none,
1906+
"'@_spiOnly' requires setting the frontend flag '-experimental-spi-only-imports'",
1907+
())
19051908

19061909
// Opaque return types
19071910
ERROR(opaque_type_invalid_constraint,none,

include/swift/AST/Import.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ enum class ImportFlags {
8888
WeakLinked = 0x40,
8989

9090
/// Used for DenseMap.
91-
Reserved = 0x80
91+
Reserved = 0x80,
92+
93+
/// The imported module can only be referenced from SPI decls, or
94+
/// implementation details.
95+
SPIOnly = 0x100
9296
};
9397

9498
/// \see ImportFlags

include/swift/AST/Module.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,11 +696,13 @@ class ModuleDecl
696696
Default = 1 << 1,
697697
/// Include imports declared with `@_implementationOnly`.
698698
ImplementationOnly = 1 << 2,
699-
/// Include imports of SPIs declared with `@_spi`
699+
/// Include imports of SPIs declared with `@_spi`.
700700
SPIAccessControl = 1 << 3,
701+
/// Include imports declared with `@_spiOnly`.
702+
SPIOnly = 1 << 4,
701703
/// Include imports shadowed by a cross-import overlay. Unshadowed imports
702704
/// are included whether or not this flag is specified.
703-
ShadowedByCrossImportOverlay = 1 << 4
705+
ShadowedByCrossImportOverlay = 1 << 5
704706
};
705707
/// \sa getImportedModules
706708
using ImportFilter = OptionSet<ImportFilterKind>;

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ namespace swift {
456456
// FrontendOptions.
457457
bool AllowModuleWithCompilerErrors = false;
458458

459+
/// Enable using @_spiOnly on import decls.
460+
bool EnableSPIOnlyImports = false;
461+
459462
/// A helper enum to represent whether or not we customized the default
460463
/// ASTVerifier behavior via a frontend flag. By default, we do not
461464
/// customize.

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,4 +1110,8 @@ def enable_emit_generic_class_ro_t_list :
11101110
Flag<["-"], "enable-emit-generic-class-ro_t-list">,
11111111
HelpText<"Enable emission of a section with references to class_ro_t of "
11121112
"generic class patterns">;
1113+
1114+
def experimental_spi_only_imports :
1115+
Flag<["-"], "experimental-spi-only-imports">,
1116+
HelpText<"Enable use of @_spiOnly imports">;
11131117
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

lib/AST/ImportCache.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ ImportSet &ImportCache::getImportSet(const DeclContext *dc) {
195195
file->getImportedModules(imports,
196196
{ModuleDecl::ImportFilterKind::Default,
197197
ModuleDecl::ImportFilterKind::ImplementationOnly,
198+
ModuleDecl::ImportFilterKind::SPIOnly,
198199
ModuleDecl::ImportFilterKind::SPIAccessControl});
199200
}
200201

@@ -279,6 +280,7 @@ ImportCache::getAllAccessPathsNotShadowedBy(const ModuleDecl *mod,
279280
file->getImportedModules(stack,
280281
{ModuleDecl::ImportFilterKind::Default,
281282
ModuleDecl::ImportFilterKind::ImplementationOnly,
283+
ModuleDecl::ImportFilterKind::SPIOnly,
282284
ModuleDecl::ImportFilterKind::SPIAccessControl});
283285
}
284286

lib/AST/Module.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,8 @@ SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
15961596
requiredFilter |= ModuleDecl::ImportFilterKind::Exported;
15971597
else if (desc.options.contains(ImportFlags::ImplementationOnly))
15981598
requiredFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
1599+
else if (desc.options.contains(ImportFlags::SPIOnly))
1600+
requiredFilter |= ModuleDecl::ImportFilterKind::SPIOnly;
15991601
else if (desc.options.contains(ImportFlags::SPIAccessControl))
16001602
requiredFilter |= ModuleDecl::ImportFilterKind::SPIAccessControl;
16011603
else
@@ -1904,6 +1906,7 @@ SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const
19041906

19051907
ModuleDecl::ImportFilter topLevelFilter = filter;
19061908
topLevelFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
1909+
topLevelFilter |= ModuleDecl::ImportFilterKind::SPIOnly;
19071910
topLevel->getImportedModules(stack, topLevelFilter);
19081911

19091912
// Make sure the top-level module is first; we want pre-order-ish traversal.
@@ -2600,6 +2603,7 @@ canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const {
26002603
// @_implementationOnly or @_spi.
26012604
ModuleDecl::ImportFilter filter = {
26022605
ModuleDecl::ImportFilterKind::ImplementationOnly,
2606+
ModuleDecl::ImportFilterKind::SPIOnly,
26032607
ModuleDecl::ImportFilterKind::SPIAccessControl
26042608
};
26052609
SmallVector<ImportedModule, 4> results;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
721721
}
722722
}
723723

724+
Opts.EnableSPIOnlyImports = Args.hasArg(OPT_experimental_spi_only_imports);
725+
724726
if (Opts.EnableSwift3ObjCInference) {
725727
if (const Arg *A = Args.getLastArg(
726728
OPT_warn_swift3_objc_inference_minimal,

0 commit comments

Comments
 (0)