Skip to content

Commit 8e0d3ba

Browse files
authored
Merge pull request #36103 from DougGregor/concurrent-module-interface-old-swift
2 parents bd0d3ac + 5f9b898 commit 8e0d3ba

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,8 @@ LANGUAGE_FEATURE(AsyncAwait, 296, "async/await", true)
3939
LANGUAGE_FEATURE(MarkerProtocol, 0, "@_marker protocol", true)
4040
LANGUAGE_FEATURE(Actors, 0, "actors", langOpts.EnableExperimentalConcurrency)
4141
LANGUAGE_FEATURE(ConcurrentFunctions, 0, "@concurrent functions", true)
42+
LANGUAGE_FEATURE(RethrowsProtocol, 0, "@rethrows protocol", true)
43+
LANGUAGE_FEATURE(GlobalActors, 0, "Global actors", langOpts.EnableExperimentalConcurrency)
44+
LANGUAGE_FEATURE(BuiltinJob, 0, "Builtin.Job type", true)
4245

4346
#undef LANGUAGE_FEATURE

lib/AST/ASTPrinter.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTMangler.h"
2020
#include "swift/AST/ASTVisitor.h"
2121
#include "swift/AST/Attr.h"
22+
#include "swift/AST/Builtins.h"
2223
#include "swift/AST/ClangModuleLoader.h"
2324
#include "swift/AST/Comment.h"
2425
#include "swift/AST/Decl.h"
@@ -2511,6 +2512,100 @@ static bool usesFeatureConcurrentFunctions(Decl *decl) {
25112512
return false;
25122513
}
25132514

2515+
static bool usesFeatureRethrowsProtocol(
2516+
Decl *decl, SmallPtrSet<Decl *, 16> &checked) {
2517+
// Make sure we don't recurse.
2518+
if (!checked.insert(decl).second)
2519+
return false;
2520+
2521+
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
2522+
if (proto->getAttrs().hasAttribute<AtRethrowsAttr>())
2523+
return true;
2524+
}
2525+
2526+
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2527+
if (auto proto = ext->getSelfProtocolDecl())
2528+
if (usesFeatureRethrowsProtocol(proto, checked))
2529+
return true;
2530+
}
2531+
2532+
if (auto genericSig = decl->getInnermostDeclContext()
2533+
->getGenericSignatureOfContext()) {
2534+
for (const auto &req : genericSig->getRequirements()) {
2535+
if (req.getKind() == RequirementKind::Conformance &&
2536+
usesFeatureRethrowsProtocol(
2537+
req.getSecondType()->getAs<ProtocolType>()->getDecl(), checked))
2538+
return true;
2539+
}
2540+
}
2541+
2542+
if (auto value = dyn_cast<ValueDecl>(decl)) {
2543+
if (Type type = value->getInterfaceType()) {
2544+
bool hasRethrowsProtocol = type.findIf([&](Type type) {
2545+
if (auto nominal = type->getAnyNominal()) {
2546+
if (usesFeatureRethrowsProtocol(nominal, checked))
2547+
return true;
2548+
}
2549+
2550+
return false;
2551+
});
2552+
2553+
if (hasRethrowsProtocol)
2554+
return true;
2555+
}
2556+
}
2557+
2558+
return false;
2559+
}
2560+
2561+
static bool usesFeatureRethrowsProtocol(Decl *decl) {
2562+
SmallPtrSet<Decl *, 16> checked;
2563+
return usesFeatureRethrowsProtocol(decl, checked);
2564+
}
2565+
2566+
static bool usesFeatureGlobalActors(Decl *decl) {
2567+
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
2568+
if (nominal->getAttrs().hasAttribute<GlobalActorAttr>())
2569+
return true;
2570+
}
2571+
2572+
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2573+
if (auto nominal = ext->getExtendedNominal())
2574+
if (usesFeatureGlobalActors(nominal))
2575+
return true;
2576+
}
2577+
2578+
return false;
2579+
}
2580+
2581+
static bool usesFeatureBuiltinJob(Decl *decl) {
2582+
auto typeHasBuiltinJob = [](Type type) {
2583+
return type.findIf([&](Type type) {
2584+
if (auto builtinTy = type->getAs<BuiltinType>())
2585+
return builtinTy->getBuiltinTypeKind() == BuiltinTypeKind::BuiltinJob;
2586+
2587+
return false;
2588+
});
2589+
};
2590+
2591+
if (auto value = dyn_cast<ValueDecl>(decl)) {
2592+
if (Type type = value->getInterfaceType()) {
2593+
if (typeHasBuiltinJob(type))
2594+
return true;
2595+
}
2596+
}
2597+
2598+
if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
2599+
for (unsigned idx : range(patternBinding->getNumPatternEntries())) {
2600+
if (Type type = patternBinding->getPattern(idx)->getType())
2601+
if (typeHasBuiltinJob(type))
2602+
return true;
2603+
}
2604+
}
2605+
2606+
return false;
2607+
}
2608+
25142609
/// Determine the set of "new" features used on a given declaration.
25152610
///
25162611
/// Note: right now, all features we check for are "new". At some point, we'll

test/ModuleInterface/features.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ public class OldSchool: MP {
6767
public func takeClass() async { }
6868
}
6969

70+
// CHECK: #if compiler(>=5.3) && $RethrowsProtocol
71+
// CHECK-NEXT: @rethrows public protocol RP
72+
@rethrows public protocol RP {
73+
func f() throws
74+
}
75+
76+
// CHECK: #if compiler(>=5.3) && $RethrowsProtocol
77+
// CHECK-NEXT: public func acceptsRP
78+
public func acceptsRP<T: RP>(_: T) { }
79+
7080
// CHECK-NOT: #if compiler(>=5.3) && $MarkerProtocol
7181
// CHECK: extension Array : FeatureTest.MP where Element : FeatureTest.MP {
7282
extension Array: FeatureTest.MP where Element : FeatureTest.MP { }
@@ -77,6 +87,14 @@ extension Array: FeatureTest.MP where Element : FeatureTest.MP { }
7787
extension OldSchool: UnsafeConcurrentValue { }
7888
// CHECK-NEXT: }
7989

90+
// CHECK: #if compiler(>=5.3) && $GlobalActors
91+
// CHECK-NEXT: @globalActor public struct SomeGlobalActor
92+
@globalActor
93+
public struct SomeGlobalActor {
94+
public static let shared = MyActor()
95+
}
96+
97+
8098
// CHECK: #if compiler(>=5.3) && $AsyncAwait
8199
// CHECK-NEXT: func runSomethingSomewhere
82100
// CHECK-NEXT: #endif

0 commit comments

Comments
 (0)