Skip to content

Commit c1837c9

Browse files
committed
Introduce separately-imported stdlib overlays
The `_Concurrency` and `_StringProcessing` modules are implementation details of the standard library; to developers, their contents should behave as though they are declared directly within module `Swift`. This is the exact same behavior we expect of cross-import overlays, so treat these modules as though they are cross-import overlays with no bystanding module. Because these modules don’t re-export the standard library, it’s also necessary to treat `Swift` as a separately imported overlay of itself; do so and make that actually work.
1 parent 8362997 commit c1837c9

File tree

9 files changed

+57
-10
lines changed

9 files changed

+57
-10
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
> [!NOTE]
44
> This is in reverse chronological order, so newer entries are added to the top.
55
6+
## Swift (next)
7+
8+
* Concurrency-related APIs like `Task` and string-processing-related APIs like `Regex` can now be qualified by the name
9+
`Swift`, just like other standard library APIs:
10+
11+
```swift
12+
Swift.Task { ... }
13+
func match(_ regex: Swift.Regex<(Substring)>) { ... }
14+
```
15+
16+
The old `_Concurrency` and `_StringProcessing` names are still supported for backwards compatibility, and Embedded
17+
Swift projects must still explicitly `import _Concurrency` to access councurrency APIs.
18+
619
## Swift 6.2
720

821
* [SE-0472][]:

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,10 @@ class ASTContext final {
12941294
return const_cast<ASTContext *>(this)->getStdlibModule(false);
12951295
}
12961296

1297+
/// Names of underscored modules whose contents, if imported, should be
1298+
/// treated as separately-imported overlays of the standard library module.
1299+
Identifier StdlibOverlayNames[2];
1300+
12971301
/// Insert an externally-sourced module into the set of known loaded modules
12981302
/// in this context.
12991303
void addLoadedModule(ModuleDecl *M);

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ ASTContext::ASTContext(
839839
// Initialize all of the known identifiers.
840840
#define IDENTIFIER_WITH_NAME(Name, IdStr) Id_##Name = getIdentifier(IdStr);
841841
#include "swift/AST/KnownIdentifiers.def"
842+
843+
StdlibOverlayNames[0] = Id_Concurrency;
844+
StdlibOverlayNames[1] = Id_StringProcessing;
842845

843846
// Record the initial set of search paths.
844847
for (const auto &path : SearchPathOpts.getImportSearchPaths())

lib/AST/DeclContext.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,16 @@ DeclContext *DeclContext::getModuleScopeContext() const {
447447

448448
void DeclContext::getSeparatelyImportedOverlays(
449449
ModuleDecl *declaring, SmallVectorImpl<ModuleDecl *> &overlays) const {
450+
if (declaring->isStdlibModule()) {
451+
auto &ctx = getASTContext();
452+
for (auto overlayName: ctx.StdlibOverlayNames) {
453+
if (auto module = ctx.getLoadedModule(overlayName))
454+
overlays.push_back(module);
455+
}
456+
overlays.push_back(declaring);
457+
return;
458+
}
459+
450460
if (auto SF = getOutermostParentSourceFile())
451461
SF->getSeparatelyImportedOverlays(declaring, overlays);
452462
}

lib/AST/Module.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,12 @@ ModuleDecl::getDeclaringModuleAndBystander() {
24322432
if (!hasUnderscoredNaming())
24332433
return *(declaringModuleAndBystander = {nullptr, Identifier()});
24342434

2435+
// If this is one of the stdlib overlays, indicate as much.
2436+
auto &ctx = getASTContext();
2437+
if (llvm::is_contained(ctx.StdlibOverlayNames, getRealName()))
2438+
return *(declaringModuleAndBystander = { ctx.getStdlibModule(),
2439+
Identifier() });
2440+
24352441
// Search the transitive set of imported @_exported modules to see if any have
24362442
// this module as their overlay.
24372443
SmallPtrSet<ModuleDecl *, 16> seen;
@@ -2511,7 +2517,8 @@ bool ModuleDecl::getRequiredBystandersIfCrossImportOverlay(
25112517
auto *clangModule = declaring->getUnderlyingModuleIfOverlay();
25122518
auto current = std::make_pair(this, Identifier());
25132519
while ((current = current.first->getDeclaringModuleAndBystander()).first) {
2514-
bystanderNames.push_back(current.second);
2520+
if (!current.second.empty())
2521+
bystanderNames.push_back(current.second);
25152522
if (current.first == declaring || current.first == clangModule)
25162523
return true;
25172524
}

lib/AST/ModuleNameLookup.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,18 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
163163
moduleOrFile->getParentModule(), overlays);
164164
if (!overlays.empty()) {
165165
// If so, look in each of those overlays.
166-
for (auto overlay : overlays)
167-
lookupInModule(decls, overlay, accessPath, moduleScopeContext, options);
166+
bool selfOverlay = false;
167+
for (auto overlay : overlays) {
168+
if (overlay == moduleOrFile->getParentModule())
169+
selfOverlay = true;
170+
else
171+
lookupInModule(decls, overlay, accessPath, moduleScopeContext,
172+
options);
173+
}
168174
// FIXME: This may not work gracefully if more than one of these lookups
169175
// finds something.
170-
return;
176+
if (!selfOverlay)
177+
return;
171178
}
172179

173180
const size_t initialCount = decls.size();

lib/IDE/CompletionLookup.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,11 +2182,9 @@ bool CompletionLookup::tryModuleCompletions(Type ExprType,
21822182
// If the module is shadowed by a separately imported overlay(s), look up
21832183
// the symbols from the overlay(s) instead.
21842184
SmallVector<ModuleDecl *, 1> ShadowingOrOriginal;
2185-
if (auto *SF = CurrDeclContext->getParentSourceFile()) {
2186-
SF->getSeparatelyImportedOverlays(M, ShadowingOrOriginal);
2187-
if (ShadowingOrOriginal.empty())
2188-
ShadowingOrOriginal.push_back(M);
2189-
}
2185+
CurrDeclContext->getSeparatelyImportedOverlays(M, ShadowingOrOriginal);
2186+
if (ShadowingOrOriginal.empty())
2187+
ShadowingOrOriginal.push_back(M);
21902188
for (ModuleDecl *M : ShadowingOrOriginal) {
21912189
RequestedResultsTy Request =
21922190
RequestedResultsTy::fromModule(M, Filter).needLeadingDot(needDot());

test/Concurrency/concurrency_module_shadowing.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ func f(_ t : UnsafeCurrentTask) -> Bool {
1717

1818
@available(SwiftStdlib 5.1, *)
1919
func g(_: _Concurrency.UnsafeCurrentTask) {}
20+
21+
// Should also be allowed since _Concurrency is a separately-imported overlay of
22+
// the standard library.
23+
@available(SwiftStdlib 5.1, *)
24+
func h(_: Swift.UnsafeCurrentTask) {}

test/Concurrency/global_actor_function_types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ struct GlobalType {}
408408

409409
@_Concurrency.MainActor
410410
extension GlobalType {
411-
@_Concurrency.MainActor static func ==(
411+
@Swift.MainActor static func ==(
412412
lhs: GlobalType,
413413
rhs: GlobalType
414414
) -> Bool { true }

0 commit comments

Comments
 (0)