Skip to content

Commit b8d2680

Browse files
authored
Merge branch 'release/5.9' into pick-wip-delegation-chain-fix-executors
2 parents 2ba2332 + bc60914 commit b8d2680

File tree

49 files changed

+914
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+914
-151
lines changed

include/swift/AST/CASTBridging.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ void Plugin_setCapability(PluginHandle handle, PluginCapabilityPtr data);
313313
/// Get a capability data set by \c Plugin_setCapability .
314314
PluginCapabilityPtr _Nullable Plugin_getCapability(PluginHandle handle);
315315

316+
/// Get the executable file path of the plugin.
317+
const char *Plugin_getExecutableFilePath(PluginHandle handle);
318+
316319
/// Lock the plugin. Clients should lock it during sending and recving the
317320
/// response.
318321
void Plugin_lock(PluginHandle handle);

include/swift/AST/Decl.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3879,8 +3879,13 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
38793879
/// Find the 'RemoteCallArgument(label:name:value:)' initializer function.
38803880
ConstructorDecl *getDistributedRemoteCallArgumentInitFunction() const;
38813881

3882-
/// Get the move-only `enqueue(Job)` protocol requirement function on the `Executor` protocol.
3882+
/// Get the move-only `enqueue(ExecutorJob)` protocol requirement function on the `Executor` protocol.
38833883
AbstractFunctionDecl *getExecutorOwnedEnqueueFunction() const;
3884+
/// This method should be deprecated and removed
3885+
/// Get the move-only `enqueue(Job)` protocol requirement function on the `Executor` protocol.
3886+
AbstractFunctionDecl *getExecutorLegacyOwnedEnqueueFunction() const;
3887+
/// Get the move-only `enqueue(UnownedJob)` protocol requirement function on the `Executor` protocol.
3888+
AbstractFunctionDecl *getExecutorLegacyUnownedEnqueueFunction() const;
38843889

38853890
/// Collect the set of protocols to which this type should implicitly
38863891
/// conform, such as AnyObject (for classes).

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6521,7 +6521,11 @@ WARNING(hashvalue_implementation,Deprecation,
65216521

65226522
WARNING(executor_enqueue_unowned_implementation,Deprecation,
65236523
"'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; "
6524-
"conform type %0 to 'Executor' by implementing 'func enqueue(Job)' instead",
6524+
"conform type %0 to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead",
6525+
(Type))
6526+
WARNING(executor_enqueue_deprecated_owned_job_implementation,Deprecation,
6527+
"'Executor.enqueue(Job)' is deprecated as a protocol requirement; "
6528+
"conform type %0 to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead",
65256529
(Type))
65266530

65276531
//------------------------------------------------------------------------------

include/swift/AST/PluginRegistry.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef SWIFT_PLUGIN_REGISTRY_H
1313
#define SWIFT_PLUGIN_REGISTRY_H
1414

15+
#include "swift/Basic/StringExtras.h"
1516
#include "llvm/ADT/ArrayRef.h"
1617
#include "llvm/ADT/StringMap.h"
1718
#include "llvm/ADT/StringRef.h"
@@ -139,6 +140,10 @@ class LoadedExecutablePlugin {
139140

140141
llvm::sys::procid_t getPid() { return Process->pid; }
141142

143+
NullTerminatedStringRef getExecutablePath() {
144+
return {ExecutablePath.c_str(), ExecutablePath.size()};
145+
}
146+
142147
const void *getCapability() { return capability; };
143148
void setCapability(const void *newValue) { capability = newValue; };
144149

lib/AST/CASTBridging.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,11 @@ void Plugin_setCapability(PluginHandle handle, PluginCapabilityPtr data) {
642642
plugin->setCapability(data);
643643
}
644644

645+
const char *Plugin_getExecutableFilePath(PluginHandle handle) {
646+
auto *plugin = static_cast<LoadedExecutablePlugin *>(handle);
647+
return plugin->getExecutablePath().data();
648+
}
649+
645650
void Plugin_lock(PluginHandle handle) {
646651
auto *plugin = static_cast<LoadedExecutablePlugin *>(handle);
647652
plugin->lock();

lib/AST/Decl.cpp

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5305,6 +5305,48 @@ VarDecl *NominalTypeDecl::getGlobalActorInstance() const {
53055305
AbstractFunctionDecl *
53065306
NominalTypeDecl::getExecutorOwnedEnqueueFunction() const {
53075307
auto &C = getASTContext();
5308+
StructDecl *executorJobDecl = C.getExecutorJobDecl();
5309+
if (!executorJobDecl)
5310+
return nullptr;
5311+
5312+
auto proto = dyn_cast<ProtocolDecl>(this);
5313+
if (!proto)
5314+
return nullptr;
5315+
5316+
llvm::SmallVector<ValueDecl *, 2> results;
5317+
lookupQualified(getSelfNominalTypeDecl(),
5318+
DeclNameRef(C.Id_enqueue),
5319+
NL_ProtocolMembers,
5320+
results);
5321+
5322+
for (auto candidate: results) {
5323+
// we're specifically looking for the Executor protocol requirement
5324+
if (!isa<ProtocolDecl>(candidate->getDeclContext()))
5325+
continue;
5326+
5327+
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(candidate)) {
5328+
auto params = funcDecl->getParameters();
5329+
5330+
if (params->size() != 1)
5331+
continue;
5332+
5333+
if ((params->get(0)->getSpecifier() == ParamSpecifier::LegacyOwned ||
5334+
params->get(0)->getSpecifier() == ParamSpecifier::Consuming) &&
5335+
params->get(0)->getInterfaceType()->isEqual(executorJobDecl->getDeclaredInterfaceType())) {
5336+
return funcDecl;
5337+
}
5338+
}
5339+
}
5340+
5341+
return nullptr;
5342+
}
5343+
5344+
AbstractFunctionDecl *
5345+
NominalTypeDecl::getExecutorLegacyOwnedEnqueueFunction() const {
5346+
auto &C = getASTContext();
5347+
StructDecl *legacyJobDecl = C.getJobDecl();
5348+
if (!legacyJobDecl)
5349+
return nullptr;
53085350

53095351
auto proto = dyn_cast<ProtocolDecl>(this);
53105352
if (!proto)
@@ -5322,11 +5364,51 @@ NominalTypeDecl::getExecutorOwnedEnqueueFunction() const {
53225364
continue;
53235365

53245366
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(candidate)) {
5325-
if (funcDecl->getParameters()->size() != 1)
5367+
auto params = funcDecl->getParameters();
5368+
5369+
if (params->size() != 1)
53265370
continue;
53275371

5372+
if ((params->get(0)->getSpecifier() == ParamSpecifier::LegacyOwned ||
5373+
params->get(0)->getSpecifier() == ParamSpecifier::Consuming) &&
5374+
params->get(0)->getType()->isEqual(legacyJobDecl->getDeclaredInterfaceType())) {
5375+
return funcDecl;
5376+
}
5377+
}
5378+
}
5379+
5380+
return nullptr;
5381+
}
5382+
5383+
AbstractFunctionDecl *
5384+
NominalTypeDecl::getExecutorLegacyUnownedEnqueueFunction() const {
5385+
auto &C = getASTContext();
5386+
StructDecl *unownedJobDecl = C.getUnownedJobDecl();
5387+
if (!unownedJobDecl)
5388+
return nullptr;
5389+
5390+
auto proto = dyn_cast<ProtocolDecl>(this);
5391+
if (!proto)
5392+
return nullptr;
5393+
5394+
llvm::SmallVector<ValueDecl *, 2> results;
5395+
lookupQualified(getSelfNominalTypeDecl(),
5396+
DeclNameRef(C.Id_enqueue),
5397+
NL_ProtocolMembers,
5398+
results);
5399+
5400+
for (auto candidate: results) {
5401+
// we're specifically looking for the Executor protocol requirement
5402+
if (!isa<ProtocolDecl>(candidate->getDeclContext()))
5403+
continue;
5404+
5405+
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(candidate)) {
53285406
auto params = funcDecl->getParameters();
5329-
if (params->get(0)->getSpecifier() == ParamSpecifier::LegacyOwned) { // TODO: make this Consuming
5407+
5408+
if (params->size() != 1)
5409+
continue;
5410+
5411+
if (params->get(0)->getType()->isEqual(unownedJobDecl->getDeclaredInterfaceType())) {
53305412
return funcDecl;
53315413
}
53325414
}

lib/AST/Module.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,10 +1768,18 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
17681768
/// appropriate.
17691769
static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
17701770
Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) {
1771-
// All metatypes are Sendable and Copyable
1772-
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
1773-
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
1774-
ASTContext &ctx = protocol->getASTContext();
1771+
ASTContext &ctx = protocol->getASTContext();
1772+
1773+
// Only metatypes of Copyable types are Copyable.
1774+
if (protocol->isSpecificProtocol(KnownProtocolKind::Copyable) &&
1775+
!metatypeType->getInstanceType()->isPureMoveOnly()) {
1776+
return ProtocolConformanceRef(
1777+
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
1778+
BuiltinConformanceKind::Synthesized));
1779+
}
1780+
1781+
// All metatypes are Sendable
1782+
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
17751783
return ProtocolConformanceRef(
17761784
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
17771785
BuiltinConformanceKind::Synthesized));

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,6 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
16201620
MemberLookupTable &table,
16211621
DeclName name,
16221622
TypeOrExtensionDecl container) {
1623-
16241623
// Trigger the expansion of member macros on the container, if any of the
16251624
// names match.
16261625
{
@@ -1645,7 +1644,7 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
16451644
MacroIntroducedNameTracker nameTracker;
16461645
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
16471646
forEachPotentialResolvedMacro(
1648-
member->getModuleContext(), med->getMacroName(),
1647+
dc->getModuleScopeContext(), med->getMacroName(),
16491648
MacroRole::Declaration, nameTracker);
16501649
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
16511650
nameTracker.attachedTo = dyn_cast<ValueDecl>(member);

lib/AST/PluginRegistry.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ LoadedExecutablePlugin::PluginProcess::~PluginProcess() {
178178

179179
LoadedExecutablePlugin::~LoadedExecutablePlugin() {
180180
// Let ASTGen to cleanup things.
181-
this->cleanup();
181+
if (this->cleanup)
182+
this->cleanup();
182183
}
183184

184185
ssize_t LoadedExecutablePlugin::PluginProcess::read(void *buf,

lib/ASTGen/Sources/ASTGen/PluginHost.swift

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,32 @@ import CBasicBridging
1515
import SwiftSyntax
1616
import swiftLLVMJSON
1717

18-
enum PluginError: Error {
19-
case stalePlugin
20-
case failedToSendMessage
21-
case failedToReceiveMessage
22-
case invalidReponseKind
18+
enum PluginError: String, Error, CustomStringConvertible {
19+
case stalePlugin = "plugin is stale"
20+
case failedToSendMessage = "failed to send request to plugin"
21+
case failedToReceiveMessage = "failed to receive result from plugin"
22+
case invalidReponseKind = "plugin returned invalid result"
23+
24+
var description: String { rawValue }
2325
}
2426

2527
@_cdecl("swift_ASTGen_initializePlugin")
2628
public func _initializePlugin(
27-
opaqueHandle: UnsafeMutableRawPointer
28-
) {
29+
opaqueHandle: UnsafeMutableRawPointer,
30+
cxxDiagnosticEngine: UnsafeMutablePointer<UInt8>?
31+
) -> Bool {
2932
let plugin = CompilerPlugin(opaqueHandle: opaqueHandle)
30-
plugin.initialize()
33+
let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: cxxDiagnosticEngine)
34+
35+
do {
36+
try plugin.initialize()
37+
return true
38+
} catch {
39+
diagEngine?.diagnose(
40+
message: "compiler plugin not loaded: '\(plugin.executableFilePath); failed to initialize",
41+
severity: .warning)
42+
return false
43+
}
3144
}
3245

3346
@_cdecl("swift_ASTGen_deinitializePlugin")
@@ -48,17 +61,19 @@ func swift_ASTGen_pluginServerLoadLibraryPlugin(
4861
cxxDiagnosticEngine: UnsafeMutablePointer<UInt8>?
4962
) -> Bool {
5063
let plugin = CompilerPlugin(opaqueHandle: opaqueHandle)
64+
let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: cxxDiagnosticEngine)
65+
66+
if plugin.capability?.features.contains(.loadPluginLibrary) != true {
67+
// This happens only if invalid plugin server was passed to `-external-plugin-path`.
68+
diagEngine?.diagnose(
69+
message: "compiler plugin not loaded: '\(libraryPath); invalid plugin server",
70+
severity: .warning)
71+
return false
72+
}
5173
assert(plugin.capability?.features.contains(.loadPluginLibrary) == true)
5274
let libraryPath = String(cString: libraryPath)
5375
let moduleName = String(cString: moduleName)
5476

55-
let diagEngine: PluginDiagnosticsEngine?
56-
if let cxxDiagnosticEngine = cxxDiagnosticEngine {
57-
diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: cxxDiagnosticEngine)
58-
} else {
59-
diagEngine = nil
60-
}
61-
6277
do {
6378
let result = try plugin.sendMessageAndWaitWithoutLock(
6479
.loadPluginLibrary(libraryPath: libraryPath, moduleName: moduleName)
@@ -69,7 +84,9 @@ func swift_ASTGen_pluginServerLoadLibraryPlugin(
6984
diagEngine?.emit(diagnostics);
7085
return loaded
7186
} catch {
72-
diagEngine?.diagnose(error: error)
87+
diagEngine?.diagnose(
88+
message: "compiler plugin not loaded: '\(libraryPath); \(error)",
89+
severity: .warning)
7390
return false
7491
}
7592
}
@@ -136,20 +153,15 @@ struct CompilerPlugin {
136153
}
137154

138155
/// Initialize the plugin. This should be called inside lock.
139-
func initialize() {
140-
do {
141-
// Get capability.
142-
let response = try self.sendMessageAndWaitWithoutLock(.getCapability)
143-
guard case .getCapabilityResult(let capability) = response else {
144-
throw PluginError.invalidReponseKind
145-
}
146-
let ptr = UnsafeMutablePointer<Capability>.allocate(capacity: 1)
147-
ptr.initialize(to: .init(capability))
148-
Plugin_setCapability(opaqueHandle, UnsafeRawPointer(ptr))
149-
} catch {
150-
assertionFailure(String(describing: error))
151-
return
156+
func initialize() throws {
157+
// Get capability.
158+
let response = try self.sendMessageAndWaitWithoutLock(.getCapability)
159+
guard case .getCapabilityResult(let capability) = response else {
160+
throw PluginError.invalidReponseKind
152161
}
162+
let ptr = UnsafeMutablePointer<Capability>.allocate(capacity: 1)
163+
ptr.initialize(to: .init(capability))
164+
Plugin_setCapability(opaqueHandle, UnsafeRawPointer(ptr))
153165
}
154166

155167
func deinitialize() {
@@ -169,6 +181,10 @@ struct CompilerPlugin {
169181
}
170182
return nil
171183
}
184+
185+
var executableFilePath: String {
186+
return String(cString: Plugin_getExecutableFilePath(opaqueHandle))
187+
}
172188
}
173189

174190
class PluginDiagnosticsEngine {
@@ -179,6 +195,14 @@ class PluginDiagnosticsEngine {
179195
self.cxxDiagnosticEngine = cxxDiagnosticEngine
180196
}
181197

198+
/// Failable convenience initializer for optional cxx engine pointer.
199+
convenience init?(cxxDiagnosticEngine: UnsafeMutablePointer<UInt8>?) {
200+
guard let cxxDiagnosticEngine = cxxDiagnosticEngine else {
201+
return nil
202+
}
203+
self.init(cxxDiagnosticEngine: cxxDiagnosticEngine)
204+
}
205+
182206
/// Register an 'ExportedSourceFile' to the engine. So the engine can get
183207
/// C++ SourceLoc from a pair of filename and offset.
184208
func add(exportedSourceFile: UnsafePointer<ExportedSourceFile>) {
@@ -282,6 +306,10 @@ class PluginDiagnosticsEngine {
282306
)
283307
}
284308

309+
func diagnose(message: String, severity: PluginMessage.Diagnostic.Severity) {
310+
self.emitSingle(message: message, severity: severity, position: .invalid)
311+
}
312+
285313
/// Produce the C++ source location for a given position based on a
286314
/// syntax node.
287315
private func cxxSourceLocation(

0 commit comments

Comments
 (0)