Skip to content

Commit b2808d1

Browse files
authored
Merge pull request #73381 from gottesmm/rdar120420024
[sending] Change CheckedContinuation.resume and Async{Throwing,}Stream.yield to use transferring parameters.
2 parents 4d86217 + ce1dd43 commit b2808d1

File tree

54 files changed

+707
-309
lines changed

Some content is hidden

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

54 files changed

+707
-309
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,8 @@ class ASTMangler : public Mangler {
445445
void appendRetroactiveConformances(SubstitutionMap subMap,
446446
GenericSignature sig);
447447
void appendImplFunctionType(SILFunctionType *fn, GenericSignature sig,
448-
const ValueDecl *forDecl = nullptr);
448+
const ValueDecl *forDecl = nullptr,
449+
bool isInRecursion = true);
449450
void appendOpaqueTypeArchetype(ArchetypeType *archetype,
450451
OpaqueTypeDecl *opaqueDecl,
451452
SubstitutionMap subs,
@@ -521,25 +522,29 @@ class ASTMangler : public Mangler {
521522
FunctionMangling,
522523
};
523524

524-
void appendFunction(AnyFunctionType *fn, GenericSignature sig,
525-
FunctionManglingKind functionMangling = NoFunctionMangling,
526-
const ValueDecl *forDecl = nullptr);
525+
void
526+
appendFunction(AnyFunctionType *fn, GenericSignature sig,
527+
FunctionManglingKind functionMangling = NoFunctionMangling,
528+
const ValueDecl *forDecl = nullptr,
529+
bool isRecursedInto = true);
527530
void appendFunctionType(AnyFunctionType *fn, GenericSignature sig,
528531
bool isAutoClosure = false,
529-
const ValueDecl *forDecl = nullptr);
532+
const ValueDecl *forDecl = nullptr,
533+
bool isRecursedInto = true);
530534
void appendClangType(AnyFunctionType *fn);
531535
template <typename FnType>
532536
void appendClangType(FnType *fn, llvm::raw_svector_ostream &os);
533537

534-
void appendFunctionSignature(AnyFunctionType *fn,
535-
GenericSignature sig,
538+
void appendFunctionSignature(AnyFunctionType *fn, GenericSignature sig,
536539
const ValueDecl *forDecl,
537-
FunctionManglingKind functionMangling);
540+
FunctionManglingKind functionMangling,
541+
bool isRecursedInto = true);
538542

539543
void appendFunctionInputType(ArrayRef<AnyFunctionType::Param> params,
540544
LifetimeDependenceInfo lifetimeDependenceInfo,
541545
GenericSignature sig,
542-
const ValueDecl *forDecl = nullptr);
546+
const ValueDecl *forDecl = nullptr,
547+
bool isRecursedInto = true);
543548
void appendFunctionResultType(Type resultType,
544549
GenericSignature sig,
545550
const ValueDecl *forDecl = nullptr);

include/swift/AST/Builtins.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,14 +517,14 @@ BUILTIN_SIL_OPERATION(ApplyDerivative, "applyDerivative", Special)
517517
/// applyTranspose
518518
BUILTIN_SIL_OPERATION(ApplyTranspose, "applyTranspose", Special)
519519

520-
/// withUnsafeContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async -> T
520+
/// withUnsafeContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async -> sending T
521521
///
522522
/// Unsafely capture the current continuation and pass it to the given
523523
/// function value. Returns a value of type T when the continuation is
524524
/// resumed.
525525
BUILTIN_SIL_OPERATION(WithUnsafeContinuation, "withUnsafeContinuation", Special)
526526

527-
/// withUnsafeThrowingContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async throws -> T
527+
/// withUnsafeThrowingContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async throws -> sending T
528528
///
529529
/// Unsafely capture the current continuation and pass it to the given
530530
/// function value. Returns a value of type T or throws an error when

include/swift/Basic/Features.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(NoncopyableGenerics, 427, "Noncopyable generics")
196196
SUPPRESSIBLE_LANGUAGE_FEATURE(ConformanceSuppression, 426, "Suppressible inferred conformances")
197197
SUPPRESSIBLE_LANGUAGE_FEATURE(BitwiseCopyable2, 426, "BitwiseCopyable feature")
198198
LANGUAGE_FEATURE(BodyMacros, 415, "Function body macros")
199+
LANGUAGE_FEATURE(TransferringArgsAndResults, 430, "Transferring args and results")
200+
SUPPRESSIBLE_LANGUAGE_FEATURE(SendingArgsAndResults, 430, "Sending arg and results")
199201

200202
// Swift 6
201203
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -214,8 +216,6 @@ UPCOMING_FEATURE(DynamicActorIsolation, 423, 6)
214216
UPCOMING_FEATURE(NonfrozenEnumExhaustivity, 192, 6)
215217
UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6)
216218
UPCOMING_FEATURE(BorrowingSwitch, 432, 6)
217-
UPCOMING_FEATURE(TransferringArgsAndResults, 430, 6)
218-
SUPPRESSIBLE_UPCOMING_FEATURE(SendingArgsAndResults, 430, 6)
219219

220220
// Swift 7
221221
UPCOMING_FEATURE(ExistentialAny, 335, 7)

include/swift/Demangling/TypeDecoder.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,14 @@ class ImplFunctionParam {
183183
return {};
184184
}
185185

186+
static OptionsType getSending() {
187+
OptionsType result;
188+
189+
result |= ImplParameterInfoFlags::Sending;
190+
191+
return result;
192+
}
193+
186194
ImplFunctionParam(BuiltType type, ImplParameterConvention convention,
187195
OptionsType options)
188196
: Type(type), Convention(convention), Options(options) {}
@@ -256,6 +264,12 @@ class ImplFunctionResult {
256264
return {};
257265
}
258266

267+
static OptionsType getSending() {
268+
OptionsType result;
269+
result |= ImplResultInfoFlags::IsSending;
270+
return result;
271+
}
272+
259273
ImplFunctionResult(BuiltType type, ImplResultConvention convention,
260274
ImplResultInfoOptions options = {})
261275
: Type(type), Convention(convention), Options(options) {}
@@ -1594,8 +1608,9 @@ class TypeDecoder {
15941608
if (depth > TypeDecoder::MaxDepth)
15951609
return true;
15961610

1597-
// Children: `convention, differentiability?, type`
1598-
if (node->getNumChildren() != 2 && node->getNumChildren() != 3)
1611+
// Children: `convention, differentiability?, sending?, type`
1612+
if (node->getNumChildren() != 2 && node->getNumChildren() != 3 &&
1613+
node->getNumChildren() != 4)
15991614
return true;
16001615

16011616
auto *conventionNode = node->getChild(0);
@@ -1613,7 +1628,7 @@ class TypeDecoder {
16131628
return true;
16141629

16151630
typename T::OptionsType options;
1616-
if (node->getNumChildren() == 3) {
1631+
if (node->getNumChildren() == 3 || node->getNumChildren() == 4) {
16171632
auto diffKindNode = node->getChild(1);
16181633
if (diffKindNode->getKind() !=
16191634
Node::Kind::ImplParameterResultDifferentiability)
@@ -1625,6 +1640,13 @@ class TypeDecoder {
16251640
options |= *optDiffOptions;
16261641
}
16271642

1643+
if (node->getNumChildren() == 4) {
1644+
auto sendingKindNode = node->getChild(2);
1645+
if (sendingKindNode->getKind() != Node::Kind::ImplParameterSending)
1646+
return true;
1647+
options |= T::getSending();
1648+
}
1649+
16281650
results.emplace_back(result.getType(), *convention, options);
16291651

16301652
return false;

include/swift/SIL/ApplySite.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,21 @@ class ApplySite {
470470
llvm_unreachable("covered switch");
471471
}
472472

473+
/// Return the sil_isolated operand if we have one.
474+
Operand *getIsolatedArgumentOperandOrNullPtr() {
475+
switch (ApplySiteKind(Inst->getKind())) {
476+
case ApplySiteKind::ApplyInst:
477+
return cast<ApplyInst>(Inst)->getIsolatedArgumentOperandOrNullPtr();
478+
case ApplySiteKind::BeginApplyInst:
479+
return cast<BeginApplyInst>(Inst)->getIsolatedArgumentOperandOrNullPtr();
480+
case ApplySiteKind::TryApplyInst:
481+
return cast<TryApplyInst>(Inst)->getIsolatedArgumentOperandOrNullPtr();
482+
case ApplySiteKind::PartialApplyInst:
483+
llvm_unreachable("Unhandled case");
484+
}
485+
llvm_unreachable("covered switch");
486+
}
487+
473488
/// Return a list of applied arguments without self.
474489
OperandValueArrayRef getArgumentsWithoutSelf() const {
475490
switch (ApplySiteKind(Inst->getKind())) {

include/swift/SIL/SILInstruction.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,14 +2972,15 @@ class ApplyInstBase<Impl, Base, true>
29722972
const Impl &asImpl() const { return static_cast<const Impl &>(*this); }
29732973

29742974
public:
2975+
using super::getArgument;
2976+
using super::getArgumentOperands;
2977+
using super::getArguments;
29752978
using super::getCallee;
2976-
using super::getSubstCalleeType;
2979+
using super::getCalleeOperand;
2980+
using super::getNumArguments;
29772981
using super::getSubstCalleeConv;
2982+
using super::getSubstCalleeType;
29782983
using super::hasSubstitutions;
2979-
using super::getNumArguments;
2980-
using super::getArgument;
2981-
using super::getArguments;
2982-
using super::getArgumentOperands;
29832984

29842985
/// The collection of following routines wrap the representation difference in
29852986
/// between the self substitution being first, but the self parameter of a
@@ -3064,6 +3065,21 @@ class ApplyInstBase<Impl, Base, true>
30643065
return getSubstCalleeType()->hasSelfParam();
30653066
}
30663067

3068+
Operand *getIsolatedArgumentOperandOrNullPtr() {
3069+
SILFunctionConventions conv = getSubstCalleeConv();
3070+
for (Operand &argOp : getOperandsWithoutIndirectResults()) {
3071+
// Skip the callee.
3072+
if (getCalleeOperand() == &argOp)
3073+
continue;
3074+
3075+
auto opNum = argOp.getOperandNumber() - 1;
3076+
auto paramInfo = conv.getParamInfoForSILArg(opNum);
3077+
if (paramInfo.getOptions().contains(SILParameterInfo::Isolated))
3078+
return &argOp;
3079+
}
3080+
return nullptr;
3081+
}
3082+
30673083
bool hasGuaranteedSelfArgument() const {
30683084
auto C = getSubstCalleeType()->getSelfParameter().getConvention();
30693085
return C == ParameterConvention::Direct_Guaranteed;
@@ -3077,7 +3093,7 @@ class ApplyInstBase<Impl, Base, true>
30773093
return getArguments().slice(getNumIndirectResults());
30783094
}
30793095

3080-
MutableArrayRef<Operand> getOperandsWithoutIndirectResults() const {
3096+
MutableArrayRef<Operand> getOperandsWithoutIndirectResults() {
30813097
return getArgumentOperands().slice(getNumIndirectResults());
30823098
}
30833099

lib/AST/ASTMangler.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,8 @@ getResultDifferentiability(SILResultInfo::Options options) {
20392039

20402040
void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
20412041
GenericSignature outerGenericSig,
2042-
const ValueDecl *forDecl) {
2042+
const ValueDecl *forDecl,
2043+
bool isInRecursion) {
20432044

20442045
llvm::SmallVector<char, 32> OpArgs;
20452046

@@ -2164,7 +2165,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
21642165
}
21652166

21662167
// Mangle if we have a transferring result.
2167-
if (fn->hasSendingResult())
2168+
if (isInRecursion && fn->hasSendingResult())
21682169
OpArgs.push_back('T');
21692170

21702171
// Mangle the results.
@@ -2947,7 +2948,7 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl,
29472948

29482949
void ASTMangler::appendFunction(AnyFunctionType *fn, GenericSignature sig,
29492950
FunctionManglingKind functionMangling,
2950-
const ValueDecl *forDecl) {
2951+
const ValueDecl *forDecl, bool isRecursedInto) {
29512952
// Append parameter labels right before the signature/type.
29522953
auto parameters = fn->getParams();
29532954
auto firstLabel = std::find_if(
@@ -2967,19 +2968,20 @@ void ASTMangler::appendFunction(AnyFunctionType *fn, GenericSignature sig,
29672968
}
29682969

29692970
if (functionMangling != NoFunctionMangling) {
2970-
appendFunctionSignature(fn, sig, forDecl, functionMangling);
2971+
appendFunctionSignature(fn, sig, forDecl, functionMangling, isRecursedInto);
29712972
} else {
2972-
appendFunctionType(fn, sig, /*autoclosure*/ false, forDecl);
2973+
appendFunctionType(fn, sig, /*autoclosure*/ false, forDecl, isRecursedInto);
29732974
}
29742975
}
29752976

29762977
void ASTMangler::appendFunctionType(AnyFunctionType *fn, GenericSignature sig,
29772978
bool isAutoClosure,
2978-
const ValueDecl *forDecl) {
2979+
const ValueDecl *forDecl,
2980+
bool isRecursedInto) {
29792981
assert((DWARFMangling || fn->isCanonical()) &&
29802982
"expecting canonical types when not mangling for the debugger");
29812983

2982-
appendFunctionSignature(fn, sig, forDecl, NoFunctionMangling);
2984+
appendFunctionSignature(fn, sig, forDecl, NoFunctionMangling, isRecursedInto);
29832985

29842986
bool mangleClangType = fn->getASTContext().LangOpts.UseClangFunctionTypes &&
29852987
fn->hasNonDerivableClangType();
@@ -3047,10 +3049,11 @@ void ASTMangler::appendClangType(AnyFunctionType *fn) {
30473049
void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30483050
GenericSignature sig,
30493051
const ValueDecl *forDecl,
3050-
FunctionManglingKind functionMangling) {
3052+
FunctionManglingKind functionMangling,
3053+
bool isRecursedInto) {
30513054
appendFunctionResultType(fn->getResult(), sig, forDecl);
30523055
appendFunctionInputType(fn->getParams(), fn->getLifetimeDependenceInfo(), sig,
3053-
forDecl);
3056+
forDecl, isRecursedInto);
30543057
if (fn->isAsync())
30553058
appendOperator("Ya");
30563059
if (fn->isSendable())
@@ -3096,7 +3099,7 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30963099
break;
30973100
}
30983101

3099-
if (fn->hasSendingResult()) {
3102+
if (isRecursedInto && fn->hasSendingResult()) {
31003103
appendOperator("YT");
31013104
}
31023105

@@ -3142,19 +3145,25 @@ getDefaultOwnership(const ValueDecl *forDecl) {
31423145

31433146
static ParameterTypeFlags
31443147
getParameterFlagsForMangling(ParameterTypeFlags flags,
3145-
ParamSpecifier defaultSpecifier) {
3148+
ParamSpecifier defaultSpecifier,
3149+
bool isInRecursion = true) {
3150+
bool initiallySending = flags.isSending();
3151+
3152+
// If we have been recursed into, then remove sending from our flags.
3153+
if (!isInRecursion) {
3154+
flags = flags.withSending(false);
3155+
}
3156+
31463157
switch (auto specifier = flags.getOwnershipSpecifier()) {
31473158
// If no parameter specifier was provided, mangle as-is, because we are by
31483159
// definition using the default convention.
31493160
case ParamSpecifier::Default:
31503161
// If the legacy `__shared` or `__owned` modifier was provided, mangle as-is,
31513162
// because we need to maintain compatibility with their existing behavior.
3152-
case ParamSpecifier::LegacyShared:
31533163
case ParamSpecifier::LegacyOwned:
31543164
// `inout` should already be specified in the flags.
31553165
case ParamSpecifier::InOut:
31563166
return flags;
3157-
31583167
case ParamSpecifier::ImplicitlyCopyableConsuming:
31593168
case ParamSpecifier::Consuming:
31603169
case ParamSpecifier::Borrowing:
@@ -3163,13 +3172,23 @@ getParameterFlagsForMangling(ParameterTypeFlags flags,
31633172
flags = flags.withOwnershipSpecifier(ParamSpecifier::Default);
31643173
}
31653174
return flags;
3175+
case ParamSpecifier::LegacyShared:
3176+
// If we were originally sending and by default we are borrowing, suppress
3177+
// this and set ownership specifier to default so we do not mangle in
3178+
// __shared.
3179+
//
3180+
// This is a work around in the short term since shared borrow is not
3181+
// supported.
3182+
if (initiallySending && ParamSpecifier::Borrowing == defaultSpecifier)
3183+
return flags.withOwnershipSpecifier(ParamSpecifier::Default);
3184+
return flags;
31663185
}
31673186
}
31683187

31693188
void ASTMangler::appendFunctionInputType(
31703189
ArrayRef<AnyFunctionType::Param> params,
31713190
LifetimeDependenceInfo lifetimeDependenceInfo, GenericSignature sig,
3172-
const ValueDecl *forDecl) {
3191+
const ValueDecl *forDecl, bool isRecursedInto) {
31733192
auto defaultSpecifier = getDefaultOwnership(forDecl);
31743193

31753194
switch (params.size()) {
@@ -3192,7 +3211,7 @@ void ASTMangler::appendFunctionInputType(
31923211
appendParameterTypeListElement(
31933212
Identifier(), type,
31943213
getParameterFlagsForMangling(param.getParameterFlags(),
3195-
defaultSpecifier),
3214+
defaultSpecifier, isRecursedInto),
31963215
lifetimeDependenceInfo.getLifetimeDependenceOnParam(/*paramIndex*/ 0),
31973216
sig, nullptr);
31983217
break;
@@ -3214,7 +3233,7 @@ void ASTMangler::appendFunctionInputType(
32143233
appendParameterTypeListElement(
32153234
Identifier(), param.getPlainType(),
32163235
getParameterFlagsForMangling(param.getParameterFlags(),
3217-
defaultSpecifier),
3236+
defaultSpecifier, isRecursedInto),
32183237
lifetimeDependenceInfo.getLifetimeDependenceOnParam(paramIndex), sig,
32193238
nullptr);
32203239
appendListSeparator(isFirstParam);
@@ -3878,7 +3897,8 @@ void ASTMangler::appendDeclType(const ValueDecl *decl,
38783897
: decl->getDeclContext()->getGenericSignatureOfContext());
38793898

38803899
if (AnyFunctionType *FuncTy = type->getAs<AnyFunctionType>()) {
3881-
appendFunction(FuncTy, sig, functionMangling, decl);
3900+
appendFunction(FuncTy, sig, functionMangling, decl,
3901+
false /*is recursed into*/);
38823902
} else {
38833903
appendType(type, sig, decl);
38843904
}

0 commit comments

Comments
 (0)