Skip to content

Commit 60b3b08

Browse files
authored
Merge pull request #84358 from beccadax/common-concurrency
2 parents 11d299c + 3abbfaa commit 60b3b08

File tree

10 files changed

+93
-27
lines changed

10 files changed

+93
-27
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 concurrency 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
@@ -1293,6 +1293,10 @@ class ASTContext final {
12931293
return const_cast<ASTContext *>(this)->getStdlibModule(false);
12941294
}
12951295

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

lib/AST/ASTContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,12 @@ ASTContext::ASTContext(
838838
#define IDENTIFIER_WITH_NAME(Name, IdStr) Id_##Name = getIdentifier(IdStr);
839839
#include "swift/AST/KnownIdentifiers.def"
840840

841+
Identifier stdlibOverlayNames[] = {
842+
Id_Concurrency,
843+
Id_StringProcessing
844+
};
845+
StdlibOverlayNames = AllocateCopy(stdlibOverlayNames);
846+
841847
// Record the initial set of search paths.
842848
for (const auto &path : SearchPathOpts.getImportSearchPaths())
843849
getImpl().SearchPathsSet[path.Path] |= SearchPathKind::Import;

lib/AST/DeclContext.cpp

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

450450
void DeclContext::getSeparatelyImportedOverlays(
451451
ModuleDecl *declaring, SmallVectorImpl<ModuleDecl *> &overlays) const {
452+
if (declaring->isStdlibModule()) {
453+
auto &ctx = getASTContext();
454+
for (auto overlayName: ctx.StdlibOverlayNames) {
455+
if (auto module = ctx.getLoadedModule(overlayName))
456+
overlays.push_back(module);
457+
}
458+
overlays.push_back(declaring);
459+
return;
460+
}
461+
452462
if (auto SF = getOutermostParentSourceFile())
453463
SF->getSeparatelyImportedOverlays(declaring, overlays);
454464
}

lib/AST/Module.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,28 +2398,41 @@ void ModuleDecl::findDeclaredCrossImportOverlaysTransitive(
23982398
if (auto *clangModule = getUnderlyingModuleIfOverlay())
23992399
worklist.push_back(clangModule);
24002400

2401+
auto addOverlay = [&](Identifier overlay) {
2402+
// We don't present non-underscored overlays as part of the underlying
2403+
// module, so ignore them.
2404+
if (!overlay.hasUnderscoredNaming())
2405+
return;
2406+
2407+
ModuleDecl *overlayMod =
2408+
getASTContext().getModuleByIdentifier(overlay);
2409+
if (!overlayMod && overlayMod != this)
2410+
return;
2411+
2412+
if (seen.insert(overlayMod).second) {
2413+
overlayModules.push_back(overlayMod);
2414+
worklist.push_back(overlayMod);
2415+
if (auto *clangModule = overlayMod->getUnderlyingModuleIfOverlay())
2416+
worklist.push_back(clangModule);
2417+
}
2418+
};
2419+
24012420
while (!worklist.empty()) {
24022421
ModuleDecl *current = worklist.back();
24032422
worklist.pop_back();
2423+
2424+
if (current->isStdlibModule()) {
2425+
for (auto overlay : getASTContext().StdlibOverlayNames) {
2426+
addOverlay(overlay);
2427+
}
2428+
}
2429+
24042430
for (auto &pair: current->declaredCrossImports) {
24052431
Identifier &bystander = std::get<0>(pair);
24062432
for (auto *file: std::get<1>(pair)) {
24072433
auto overlays = file->getOverlayModuleNames(current, unused, bystander);
24082434
for (Identifier overlay: overlays) {
2409-
// We don't present non-underscored overlays as part of the underlying
2410-
// module, so ignore them.
2411-
if (!overlay.hasUnderscoredNaming())
2412-
continue;
2413-
ModuleDecl *overlayMod =
2414-
getASTContext().getModuleByName(overlay.str());
2415-
if (!overlayMod)
2416-
continue;
2417-
if (seen.insert(overlayMod).second) {
2418-
overlayModules.push_back(overlayMod);
2419-
worklist.push_back(overlayMod);
2420-
if (auto *clangModule = overlayMod->getUnderlyingModuleIfOverlay())
2421-
worklist.push_back(clangModule);
2422-
}
2435+
addOverlay(overlay);
24232436
}
24242437
}
24252438
}
@@ -2456,6 +2469,12 @@ ModuleDecl::getDeclaringModuleAndBystander() {
24562469
if (!hasUnderscoredNaming())
24572470
return *(declaringModuleAndBystander = {nullptr, Identifier()});
24582471

2472+
// If this is one of the stdlib overlays, indicate as much.
2473+
auto &ctx = getASTContext();
2474+
if (llvm::is_contained(ctx.StdlibOverlayNames, getRealName()))
2475+
return *(declaringModuleAndBystander = { ctx.getStdlibModule(),
2476+
Identifier() });
2477+
24592478
// Search the transitive set of imported @_exported modules to see if any have
24602479
// this module as their overlay.
24612480
SmallPtrSet<ModuleDecl *, 16> seen;
@@ -2535,7 +2554,8 @@ bool ModuleDecl::getRequiredBystandersIfCrossImportOverlay(
25352554
auto *clangModule = declaring->getUnderlyingModuleIfOverlay();
25362555
auto current = std::make_pair(this, Identifier());
25372556
while ((current = current.first->getDeclaringModuleAndBystander()).first) {
2538-
bystanderNames.push_back(current.second);
2557+
if (!current.second.empty())
2558+
bystanderNames.push_back(current.second);
25392559
if (current.first == declaring || current.first == clangModule)
25402560
return true;
25412561
}

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 }

validation-test/stdlib/Assert.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -o %t/Assert_Debug -Onone
3-
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -o %t/Assert_Release -O
4-
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -o %t/Assert_Unchecked -Ounchecked
2+
//
3+
// With -disable-access-control on, `_StringProcessing._internalInvariant` would shadow `Swift._internalInvariant`
4+
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -Xfrontend -disable-implicit-string-processing-module-import -o %t/Assert_Debug -Onone
5+
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -Xfrontend -disable-implicit-string-processing-module-import -o %t/Assert_Release -O
6+
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -Xfrontend -disable-implicit-string-processing-module-import -o %t/Assert_Unchecked -Ounchecked
7+
//
58
// RUN: %target-codesign %t/Assert_Debug
69
// RUN: %target-codesign %t/Assert_Release
710
// RUN: %target-codesign %t/Assert_Unchecked

0 commit comments

Comments
 (0)