From 5e9fba115ad6ba5880140db6824756d08bec795f Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Wed, 19 Nov 2025 14:22:51 -0800 Subject: [PATCH 1/4] NFC: provide deprecation & unavailable attribute macros --- include/swift/Basic/AccessControls.h | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 include/swift/Basic/AccessControls.h diff --git a/include/swift/Basic/AccessControls.h b/include/swift/Basic/AccessControls.h new file mode 100644 index 000000000000..f573eb20f75f --- /dev/null +++ b/include/swift/Basic/AccessControls.h @@ -0,0 +1,81 @@ +//===--- AccessControls.h ---------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines macros that help control access to APIs. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_ACCESSCONTROLS_H +#define SWIFT_ACCESSCONTROLS_H + +/// Deprecation warnings +#if defined(__clang__) || defined(__GNUC__) + #if !defined(SWIFT_DEPRECATED) + #define SWIFT_DEPRECATED __attribute__((deprecated)) + #endif + #if !defined(SWIFT_DEPRECATED_MSG) + #define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) + #endif +#else + #if !defined(SWIFT_DEPRECATED) + #define SWIFT_DEPRECATED + #endif + #if !defined(SWIFT_DEPRECATED_MSG) + #define SWIFT_DEPRECATED_MSG(...) + #endif +#endif + + +/// Unavailable errors +#if defined(__clang__) || defined(__GNUC__) + #if !defined(SWIFT_UNAVAILABLE) + #define SWIFT_UNAVAILABLE __attribute__((unavailable)) + #endif + #if !defined(SWIFT_UNAVAILABLE_MSG) + #define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) + #endif +#else + #if !defined(SWIFT_UNAVAILABLE) + #define SWIFT_UNAVAILABLE + #endif + #if !defined(SWIFT_UNAVAILABLE_MSG) + #define SWIFT_UNAVAILABLE_MSG(msg) + #endif +#endif + + +// Access controls that are only active when included in SILGen sources. +#if defined(SWIFT_INCLUDED_IN_SILGEN_SOURCES) + +// Override any prior definitions with these. +#define SWIFT_DEPRECATED_IN_SILGEN SWIFT_DEPRECATED +#define SWIFT_DEPRECATED_IN_SILGEN_MSG(...) SWIFT_DEPRECATED_MSG(__VA_ARGS__) +#define SWIFT_UNAVAILABLE_IN_SILGEN SWIFT_UNAVAILABLE +#define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG) SWIFT_UNAVAILABLE_MSG(MSG) + +#else + +#if !defined(SWIFT_DEPRECATED_IN_SILGEN) + #define SWIFT_DEPRECATED_IN_SILGEN +#endif +#if !defined(SWIFT_DEPRECATED_IN_SILGEN_MSG) + #define SWIFT_DEPRECATED_IN_SILGEN_MSG(...) +#endif +#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN) + #define SWIFT_UNAVAILABLE_IN_SILGEN +#endif +#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN_MSG) + #define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG) +#endif +#endif // SWIFT_INCLUDED_IN_SILGEN_SOURCES + +#endif // SWIFT_ACCESSCONTROLS_H From 199156b3073f6390bcffed65ef8931dc8aa38f16 Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Wed, 19 Nov 2025 14:24:49 -0800 Subject: [PATCH 2/4] SILGen: ban getSILArgumentConvention This function will give the wrong convention in SILGen when using -enable-sil-opaque-values. In particular, it will say arguments are indirect when they are not. --- include/swift/SIL/SILFunctionConventions.h | 5 ++--- include/swift/SIL/SILGenUtils.h | 17 +++++++++++++++++ lib/SIL/IR/SILArgument.cpp | 2 -- lib/SIL/Utils/MemAccessUtils.cpp | 7 +++++++ lib/SILGen/Cleanup.h | 2 ++ lib/SILGen/ManagedValue.h | 2 ++ lib/SILGen/SILGen.h | 2 ++ lib/SILGen/SILGenLValue.cpp | 6 ++---- 8 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 include/swift/SIL/SILGenUtils.h diff --git a/include/swift/SIL/SILFunctionConventions.h b/include/swift/SIL/SILFunctionConventions.h index d8c105f122b5..93810078fb6a 100644 --- a/include/swift/SIL/SILFunctionConventions.h +++ b/include/swift/SIL/SILFunctionConventions.h @@ -31,6 +31,7 @@ #define SWIFT_SIL_FUNCTIONCONVENTIONS_H #include "swift/AST/Types.h" +#include "swift/Basic/AccessControls.h" #include "swift/SIL/SILArgumentConvention.h" #include "swift/SIL/SILType.h" #include "llvm/Support/ErrorHandling.h" @@ -526,11 +527,9 @@ class SILFunctionConventions { - getNumIndirectSILErrorResults()]; } - /// WARNING: Do not use this from SILGen! - /// Use methods such as `isSILIndirect` or query the ParameterInfo instead. - /// /// Return the SIL argument convention of apply/entry argument at /// the given argument index. + SWIFT_UNAVAILABLE_IN_SILGEN_MSG("Use methods such as `isSILIndirect` or query the ParameterInfo instead.") SILArgumentConvention getSILArgumentConvention(unsigned index) const; /// Return the SIL type of the apply/entry argument at the given index. diff --git a/include/swift/SIL/SILGenUtils.h b/include/swift/SIL/SILGenUtils.h new file mode 100644 index 000000000000..46e80b95d117 --- /dev/null +++ b/include/swift/SIL/SILGenUtils.h @@ -0,0 +1,17 @@ +// +// Created by Kavon Farvardin on 11/19/25. +// + +#ifndef SWIFT_SILGENUTILS_H +#define SWIFT_SILGENUTILS_H + +#include "swift/SIL/SILValue.h" + +namespace swift { + +// Unsafe access may have invalid storage (e.g. a RawPointer). +bool isPossibleUnsafeAccessInvalidStorage(SILValue access, SILFunction *F); + +} // namespace swift + +#endif // SWIFT_SILGENUTILS_H diff --git a/lib/SIL/IR/SILArgument.cpp b/lib/SIL/IR/SILArgument.cpp index bf4e28c8fd2e..4e0bd8496ce1 100644 --- a/lib/SIL/IR/SILArgument.cpp +++ b/lib/SIL/IR/SILArgument.cpp @@ -87,8 +87,6 @@ SILParameterInfo SILFunctionArgument::getKnownParameterInfo() const { return getFunction()->getConventions().getParamInfoForSILArg(getIndex()); } -/// WARNING: Do not use this from SILGen! -/// Use methods such as `isSILIndirect` or query the ParameterInfo instead. SILArgumentConvention SILFunctionConventions::getSILArgumentConvention(unsigned index) const { assert(index < getNumSILArguments()); diff --git a/lib/SIL/Utils/MemAccessUtils.cpp b/lib/SIL/Utils/MemAccessUtils.cpp index e65e6b84f812..d70ee6a62f3f 100644 --- a/lib/SIL/Utils/MemAccessUtils.cpp +++ b/lib/SIL/Utils/MemAccessUtils.cpp @@ -22,6 +22,7 @@ #include "swift/SIL/SILBridging.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" +#include "swift/SIL/SILGenUtils.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/Test.h" #include "llvm/Support/Debug.h" @@ -2485,6 +2486,12 @@ void swift::checkSwitchEnumBlockArg(SILPhiArgument *arg) { } } +bool swift::isPossibleUnsafeAccessInvalidStorage(SILValue address, + SILFunction *F) { + auto storage = AccessStorage::compute(address); + return storage && !isPossibleFormalAccessStorage(storage, F); +} + bool swift::isPossibleFormalAccessStorage(const AccessStorage &storage, SILFunction *F) { switch (storage.getKind()) { diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h index 6069eecaa3c9..b0dc80515f99 100644 --- a/lib/SILGen/Cleanup.h +++ b/lib/SILGen/Cleanup.h @@ -17,6 +17,8 @@ #ifndef SWIFT_SILGEN_CLEANUP_H #define SWIFT_SILGEN_CLEANUP_H +#define SWIFT_INCLUDED_IN_SILGEN_SOURCES + #include "swift/Basic/Assertions.h" #include "swift/Basic/Debug.h" #include "swift/Basic/DiverseStack.h" diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h index 485a5acba304..32ac81b204d2 100644 --- a/lib/SILGen/ManagedValue.h +++ b/lib/SILGen/ManagedValue.h @@ -20,6 +20,8 @@ #ifndef SWIFT_LOWERING_MANAGEDVALUE_H #define SWIFT_LOWERING_MANAGEDVALUE_H +#define SWIFT_INCLUDED_IN_SILGEN_SOURCES + #include "Cleanup.h" #include "llvm/ADT/PointerIntPair.h" #include "swift/Basic/Assertions.h" diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h index b7e42360976d..ac3bf4e489fb 100644 --- a/lib/SILGen/SILGen.h +++ b/lib/SILGen/SILGen.h @@ -13,6 +13,8 @@ #ifndef SILGEN_H #define SILGEN_H +#define SWIFT_INCLUDED_IN_SILGEN_SOURCES + #include "ASTVisitor.h" #include "Cleanup.h" #include "swift/AST/ASTContext.h" diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index 7f95ca62a1f9..5fcd8805fe74 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -35,7 +35,7 @@ #include "swift/Basic/Assertions.h" #include "swift/SIL/Consumption.h" #include "swift/SIL/InstructionUtils.h" -#include "swift/SIL/MemAccessUtils.h" +#include "swift/SIL/SILGenUtils.h" #include "swift/SIL/PrettyStackTrace.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILInstruction.h" @@ -708,9 +708,7 @@ SILValue UnenforcedAccess::beginAccess(SILGenFunction &SGF, SILLocation loc, if (!SGF.getOptions().VerifyExclusivity) return address; - auto storage = AccessStorage::compute(address); - // Unsafe access may have invalid storage (e.g. a RawPointer). - if (storage && !isPossibleFormalAccessStorage(storage, &SGF.F)) + if (isPossibleUnsafeAccessInvalidStorage(address, &SGF.F)) return address; auto BAI = From 7c6d54efa691f1230c37b87aa8ffec31d87c386f Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Tue, 18 Nov 2025 17:05:10 -0800 Subject: [PATCH 3/4] OpaqueValues: fix `emitDistributedActorSystemWitnessCall` This code was not consulting SILFunctionConventions, so it was passing things indirect when they are not in sil-opaque-values. This fixes callers as well to ensure they pass arguments and results correctly in both modes. --- .../SILOptimizer/Utils/DistributedActor.h | 9 +- lib/SILGen/SILGenDistributed.cpp | 77 +++++----- lib/SILOptimizer/Utils/DistributedActor.cpp | 135 ++++++++++++------ .../Runtime/distributed_actor_decode.swift | 1 + .../distributed_actor_init_local.swift | 1 + .../distributed_actor_remote_functions.swift | 1 + 6 files changed, 136 insertions(+), 88 deletions(-) diff --git a/include/swift/SILOptimizer/Utils/DistributedActor.h b/include/swift/SILOptimizer/Utils/DistributedActor.h index 7be8bc322a3a..1cbf7b1b7fd1 100644 --- a/include/swift/SILOptimizer/Utils/DistributedActor.h +++ b/include/swift/SILOptimizer/Utils/DistributedActor.h @@ -15,6 +15,7 @@ #include "swift/AST/Decl.h" #include "llvm/ADT/ArrayRef.h" +#include "swift/SIL/SILValue.h" #include #include @@ -30,7 +31,6 @@ class SILArgument; class SILFunction; class SILLocation; class SILType; -class SILValue; /// Creates a reference to the distributed actor's \p actorSystem /// stored property. @@ -46,11 +46,16 @@ SILValue refDistributedActorSystem(SILBuilder &B, /// \param actorType If non-empty, the type of the distributed actor that is /// provided as one of the arguments. /// \param args The arguments provided to the call, not including the base. +/// \param indirectResult If the result is known to be returned indirect, +/// this is the temporary storage for it. /// \param tryTargets For a call that can throw, the normal and error basic /// blocks that the call will branch to. -void emitDistributedActorSystemWitnessCall( +/// \returns If the apply result is known to be returned directly, +/// and there are no tryTargets, then the result is returned. +std::optional emitDistributedActorSystemWitnessCall( SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base, SILType actorType, llvm::ArrayRef args, + std::optional indirectResult = std::nullopt, std::optional> tryTargets = std::nullopt); diff --git a/lib/SILGen/SILGenDistributed.cpp b/lib/SILGen/SILGenDistributed.cpp index ab4cfee42ac9..91164fc90144 100644 --- a/lib/SILGen/SILGenDistributed.cpp +++ b/lib/SILGen/SILGenDistributed.cpp @@ -63,14 +63,17 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc, auto fieldAddr = emitActorPropertyReference(SGF, loc, actorSelf, prop); - if (loweredType.isAddressOnly(SGF.F)) { + if (loweredType.isAddressOnly(SGF.F) && SGF.useLoweredAddresses()) { SGF.B.createCopyAddr(loc, value, fieldAddr, isTake, IsInitialization); } else { if (value->getType().isAddress()) { SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()), fieldAddr, SGF.getTypeLowering(loweredType), isTake, IsInitialization); } else { - value = SGF.B.emitCopyValueOperation(loc, value); + // If it's not semantically a take, copy it. + if (isTake == IsNotTake) + value = SGF.B.emitCopyValueOperation(loc, value); + SGF.B.emitStoreValueOperation( loc, value, fieldAddr, StoreOwnershipQualifier::Init); } @@ -204,20 +207,31 @@ void SILGenFunction::emitDistActorIdentityInit(ConstructorDecl *ctor, auto selfMetatype = getLoweredType(MetatypeType::get(selfTy)); SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype); - // --- create a temporary storage for the result of the call - // it will be deallocated automatically as we exit this scope VarDecl *var = classDecl->getDistributedActorIDProperty(); - auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType())); - auto temp = emitTemporaryAllocation(loc, resultTy); - - // --- emit the call itself. - emitDistributedActorSystemWitnessCall( - B, loc, C.Id_assignID, - actorSystem, getLoweredType(selfTy), - { temp, selfMetatypeValue }); - - // --- initialize the property. - initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake); + if (useLoweredAddresses()) { + // --- create a temporary storage for the result of the call + // it will be deallocated automatically as we exit this scope + auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType())); + auto temp = emitTemporaryAllocation(loc, resultTy); + + // --- emit the call itself. + emitDistributedActorSystemWitnessCall( + B, loc, C.Id_assignID, + actorSystem, getLoweredType(selfTy), + { selfMetatypeValue }, temp); + + // --- initialize the property. + initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake); + } else { + // --- emit the call itself. + auto result = emitDistributedActorSystemWitnessCall( + B, loc, C.Id_assignID, + actorSystem, getLoweredType(selfTy), + { selfMetatypeValue }); + + // --- initialize the property. + initializeProperty(*this, loc, borrowedSelfArg, var, result.value(), IsTake); + } } // TODO(distributed): rename to DistributedActorID @@ -361,27 +375,6 @@ void SILGenFunction::emitDistributedActorReady( // ==== ------------------------------------------------------------------------ // MARK: remote instance initialization -/// emit a call to the distributed actor system's resolve function: -/// -/// \verbatim -/// system.resolve(id:as:) -/// \endverbatim -static void createDistributedActorFactory_resolve( - SILGenFunction &SGF, ASTContext &C, FuncDecl *fd, SILValue idValue, - SILValue actorSystemValue, Type selfTy, SILValue selfMetatypeValue, - SILType resultTy, SILBasicBlock *normalBB, SILBasicBlock *errorBB) { - auto &B = SGF.B; - - auto loc = SILLocation(fd); - loc.markAutoGenerated(); - - // // ---- actually call system.resolve(id: id, as: Self.self) - emitDistributedActorSystemWitnessCall( - B, loc, C.Id_resolve, actorSystemValue, SGF.getLoweredType(selfTy), - { idValue, selfMetatypeValue }, - std::make_pair(normalBB, errorBB)); -} - /// Function body of: /// \verbatim /// DistributedActor.resolve( @@ -435,9 +428,15 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) { // TODO(distrib // ==== Call `try system.resolve(id: id, as: Self.self)` { - createDistributedActorFactory_resolve( - *this, C, fd, idArg, actorSystemArg, selfTy, selfMetatypeValue, - optionalReturnTy, switchBB, errorBB); + auto loc = SILLocation(fd); + loc.markAutoGenerated(); + + // // ---- actually call system.resolve(id: id, as: Self.self) + emitDistributedActorSystemWitnessCall( + B, loc, C.Id_resolve, actorSystemArg, getLoweredType(selfTy), + { idArg, selfMetatypeValue }, + /*indirectResult=*/std::nullopt, + std::make_pair(switchBB, errorBB)); } // ==== switch resolved { ... } diff --git a/lib/SILOptimizer/Utils/DistributedActor.cpp b/lib/SILOptimizer/Utils/DistributedActor.cpp index 7453082a15b3..66ea0c986085 100644 --- a/lib/SILOptimizer/Utils/DistributedActor.cpp +++ b/lib/SILOptimizer/Utils/DistributedActor.cpp @@ -20,12 +20,15 @@ namespace swift { -void emitDistributedActorSystemWitnessCall( +/// \returns the result of the call, if returned directly. +std::optional emitDistributedActorSystemWitnessCall( SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base, // types to be passed through to SubstitutionMap: SILType actorType, // call arguments, except the base which will be passed last ArrayRef args, + // pre-allocated, uninitialized indirect result storage, if needed + std::optional indirectResult, std::optional> tryTargets) { auto &F = B.getFunction(); auto &M = B.getModule(); @@ -73,7 +76,6 @@ void emitDistributedActorSystemWitnessCall( KnownProtocolKind::DistributedActor); assert(actorProto); - ProtocolConformanceRef conformance; auto distributedActorConfRef = lookupConformance( actorType.getASTType(), actorProto); assert(!distributedActorConfRef.isInvalid() && @@ -85,42 +87,61 @@ void emitDistributedActorSystemWitnessCall( subs = SubstitutionMap::get(genericSig, subTypes, subConformances); } - std::optional temporaryArgumentBuffer; - - // If the self parameter is indirect but the base is a value, put it - // into a temporary allocation. auto methodSILFnTy = methodSILTy.castTo(); - std::optional temporaryActorSystemBuffer; - if (methodSILFnTy->getSelfParameter().isFormalIndirect() && - !base->getType().isAddress()) { - auto buf = B.createAllocStack(loc, base->getType(), std::nullopt); - base = B.emitCopyValueOperation(loc, base); - B.emitStoreValueOperation( - loc, base, buf, StoreOwnershipQualifier::Init); - temporaryActorSystemBuffer = SILValue(buf); - } + SILFunctionConventions conv(methodSILFnTy, M); + + // Since this code lives outside of SILGen, manage our clean-ups manually. + SmallVector cleanups; + + auto prepareArgument = [&](SILParameterInfo param, SILValue arg) -> SILValue { + if (conv.isSILIndirect(param)) { + // Does it need temporary stack storage? + if (!arg->getType().isAddress() && + !dyn_cast(arg->getType().getASTType())) { + auto buf = B.createAllocStack(loc, arg->getType(), std::nullopt); + cleanups.push_back(buf); + + auto copy = B.emitCopyValueOperation(loc, arg); + B.emitStoreValueOperation( + loc, copy, buf, StoreOwnershipQualifier::Init); + + return buf; + } + return arg; // no temporary storage needed + } + + // Otherwise, it's a direct convention. Borrow if needed. + if (arg->getType().isAddress()) { + arg = B.emitLoadBorrowOperation(loc, arg); + cleanups.push_back(arg.getDefiningInstruction()); + } + return arg; + }; + + SILValue selfArg = prepareArgument(methodSILFnTy->getSelfParameter(), base); // === Call the method. // --- Push the arguments SmallVector allArgs; + + const bool hasIndirectResult = conv.getNumIndirectSILResults() > 0; + ASSERT(hasIndirectResult == indirectResult.has_value() && "no indirectResult storage given!"); + ASSERT(conv.getNumIndirectSILResults() <= 1); + + const bool hasDirectResult = conv.getNumDirectSILResults() > 0; + ASSERT(!(hasIndirectResult && hasDirectResult) && "indirect AND direct results aren't supported"); + ASSERT(conv.getNumDirectSILResults() <= 1); + + if (hasIndirectResult) { + allArgs.push_back(*indirectResult); + } + auto params = methodSILFnTy->getParameters(); for (size_t i = 0; i < args.size(); ++i) { - auto arg = args[i]; - if (params[i].isFormalIndirect() && - !arg->getType().isAddress() && - !dyn_cast(arg->getType().getASTType())) { - auto buf = B.createAllocStack(loc, arg->getType(), std::nullopt); - auto argCopy = B.emitCopyValueOperation(loc, arg); - B.emitStoreValueOperation( - loc, argCopy, buf, StoreOwnershipQualifier::Init); - temporaryArgumentBuffer = SILValue(buf); - allArgs.push_back(*temporaryArgumentBuffer); - } else { - allArgs.push_back(arg); - } + allArgs.push_back(prepareArgument(params[i], args[i])); } + // Push the self argument - auto selfArg = temporaryActorSystemBuffer ? *temporaryActorSystemBuffer : base; allArgs.push_back(selfArg); SILInstruction *apply; @@ -132,7 +153,7 @@ void emitDistributedActorSystemWitnessCall( apply = B.createApply(loc, witnessMethod, subs, allArgs); } - // Local function to emit a cleanup after the call. + // Local function to emit cleanups after the call in successor blocks. auto emitCleanup = [&](llvm::function_ref fn) { if (tryTargets) { { @@ -148,25 +169,45 @@ void emitDistributedActorSystemWitnessCall( } }; - // ==== If we had to create a buffers we need to clean them up - // --- Cleanup id buffer - if (temporaryArgumentBuffer) { - emitCleanup([&](SILBuilder & builder) { - auto value = builder.emitLoadValueOperation( - loc, *temporaryArgumentBuffer, LoadOwnershipQualifier::Take); - builder.emitDestroyValueOperation(loc, value); - builder.createDeallocStack(loc, *temporaryArgumentBuffer); - }); + // Emit clean-ups in reverse order, to preserve stack nesting, etc. + for (auto inst : reverse(cleanups)) { + if (auto asi = dyn_cast(inst)) { + auto buf = asi->getResult(0); + emitCleanup([&](SILBuilder & builder) { + // FIXME: could do destroy_addr rather than take + destroy_value + auto value = builder.emitLoadValueOperation( + loc, buf, LoadOwnershipQualifier::Take); + builder.emitDestroyValueOperation(loc, value); + builder.createDeallocStack(loc, buf); + }); + continue; + } + + if (auto lb = dyn_cast(inst)) { + auto borrow = lb->getResult(0); + emitCleanup([&](SILBuilder & builder) { + builder.emitEndBorrowOperation(loc, borrow); + }); + continue; + } + + if (isa(inst)) { + // no clean-ups required + continue; + } + + llvm_unreachable("unknown instruction kind to clean-up!"); } - // --- Cleanup base buffer - if (temporaryActorSystemBuffer) { - emitCleanup([&](SILBuilder & builder) { - auto value = builder.emitLoadValueOperation( - loc, *temporaryActorSystemBuffer, LoadOwnershipQualifier::Take); - builder.emitDestroyValueOperation(loc, value); - builder.createDeallocStack(loc, *temporaryActorSystemBuffer); - }); + + // If this was a try_apply, then the result is the BB argument of the + // successor block. We let our caller figure that out themselves. + // + // Otherwise, the apply had a single direct result, so we return that. + if (hasDirectResult && !tryTargets) { + return apply->getResult(0); } + + return std::nullopt; } void emitActorReadyCall(SILBuilder &B, SILLocation loc, SILValue actor, diff --git a/test/Distributed/Runtime/distributed_actor_decode.swift b/test/Distributed/Runtime/distributed_actor_decode.swift index 443a3f4094ea..a4332c78faf9 100644 --- a/test/Distributed/Runtime/distributed_actor_decode.swift +++ b/test/Distributed/Runtime/distributed_actor_decode.swift @@ -1,4 +1,5 @@ // RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s +// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // REQUIRES: executable_test // REQUIRES: concurrency diff --git a/test/Distributed/Runtime/distributed_actor_init_local.swift b/test/Distributed/Runtime/distributed_actor_init_local.swift index fa7ddb666f39..6e825d80cdb0 100644 --- a/test/Distributed/Runtime/distributed_actor_init_local.swift +++ b/test/Distributed/Runtime/distributed_actor_init_local.swift @@ -1,4 +1,5 @@ // RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s +// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // REQUIRES: executable_test // REQUIRES: concurrency diff --git a/test/Distributed/Runtime/distributed_actor_remote_functions.swift b/test/Distributed/Runtime/distributed_actor_remote_functions.swift index 993eef54a2e2..76d3518d259b 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_functions.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_functions.swift @@ -1,4 +1,5 @@ // RUN: %target-run-simple-swift(-target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s +// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // REQUIRES: executable_test // REQUIRES: concurrency From 10d80531fd77fcf62c360b32af4a0b3676c3ce95 Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Wed, 19 Nov 2025 17:22:29 -0800 Subject: [PATCH 4/4] Distributed: reenable distributed_actor_init_local.swift The issue in rdar://92952551 appears to have been resolved. --- test/Distributed/Runtime/distributed_actor_init_local.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/Distributed/Runtime/distributed_actor_init_local.swift b/test/Distributed/Runtime/distributed_actor_init_local.swift index 6e825d80cdb0..59f1f648441a 100644 --- a/test/Distributed/Runtime/distributed_actor_init_local.swift +++ b/test/Distributed/Runtime/distributed_actor_init_local.swift @@ -10,9 +10,6 @@ // UNSUPPORTED: back_deployment_runtime -// FIXME(distributed): Seems something remains incorrect here -// REQUIRES: rdar92952551 - import Distributed enum MyError: Error {