Skip to content

Commit f4efcec

Browse files
committed
[transferring] Add mangling support for transferring.
This includes runtime support for instantiating transferring param/result in function types. This is especially important since that is how we instantiate function types like: typealias Fn = (transferring X) -> (). rdar://123118061
1 parent d35dcc8 commit f4efcec

File tree

18 files changed

+302
-31
lines changed

18 files changed

+302
-31
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,9 @@ class TargetExtendedFunctionTypeFlags {
11871187

11881188
// Values for the enumerated isolation kinds
11891189
IsolatedAny = 0x00000002U,
1190+
1191+
// Values if we have a transferring result.
1192+
HasTransferringResult = 0x00000010U,
11901193
};
11911194
int_type Data;
11921195

@@ -1211,12 +1214,23 @@ class TargetExtendedFunctionTypeFlags {
12111214
(Data & ~IsolationMask) | IsolatedAny);
12121215
}
12131216

1217+
const TargetExtendedFunctionTypeFlags<int_type>
1218+
withTransferringResult(bool newValue = true) const {
1219+
return TargetExtendedFunctionTypeFlags<int_type>(
1220+
(Data & ~HasTransferringResult) |
1221+
(newValue ? HasTransferringResult : 0));
1222+
}
1223+
12141224
bool isTypedThrows() const { return bool(Data & TypedThrowsMask); }
12151225

12161226
bool isIsolatedAny() const {
12171227
return (Data & IsolationMask) == IsolatedAny;
12181228
}
12191229

1230+
bool hasTransferringResult() const {
1231+
return bool(Data & HasTransferringResult);
1232+
}
1233+
12201234
int_type getIntValue() const {
12211235
return Data;
12221236
}
@@ -1242,6 +1256,7 @@ class TargetParameterTypeFlags {
12421256
AutoClosureMask = 0x100,
12431257
NoDerivativeMask = 0x200,
12441258
IsolatedMask = 0x400,
1259+
TransferringMask = 0x800,
12451260
};
12461261
int_type Data;
12471262

@@ -1280,11 +1295,18 @@ class TargetParameterTypeFlags {
12801295
(Data & ~IsolatedMask) | (isIsolated ? IsolatedMask : 0));
12811296
}
12821297

1298+
constexpr TargetParameterTypeFlags<int_type>
1299+
withTransferring(bool isTransferring) const {
1300+
return TargetParameterTypeFlags<int_type>(
1301+
(Data & ~TransferringMask) | (isTransferring ? TransferringMask : 0));
1302+
}
1303+
12831304
bool isNone() const { return Data == 0; }
12841305
bool isVariadic() const { return Data & VariadicMask; }
12851306
bool isAutoClosure() const { return Data & AutoClosureMask; }
12861307
bool isNoDerivative() const { return Data & NoDerivativeMask; }
12871308
bool isIsolated() const { return Data & IsolatedMask; }
1309+
bool isTransferring() const { return Data & TransferringMask; }
12881310

12891311
ValueOwnership getValueOwnership() const {
12901312
return (ValueOwnership)(Data & ValueOwnershipMask);

include/swift/Demangling/Demangle.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class Node {
278278
/// Prints the whole node tree in readable form to stderr.
279279
///
280280
/// Useful to be called from the debugger.
281-
void dump();
281+
void dump() LLVM_ATTRIBUTE_USED;
282282
};
283283

284284
/// Returns the length of the swift mangling prefix of the \p SymbolName.
@@ -555,6 +555,7 @@ struct [[nodiscard]] ManglingError {
555555
InvalidImplDifferentiability,
556556
InvalidImplFunctionAttribute,
557557
InvalidImplParameterConvention,
558+
InvalidImplParameterTransferring,
558559
InvalidMetatypeRepresentation,
559560
MultiByteRelatedEntity,
560561
BadValueWitnessKind,

include/swift/Demangling/DemangleNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ NODE(ImplConvention)
133133
NODE(ImplDifferentiabilityKind)
134134
NODE(ImplErasedIsolation)
135135
NODE(ImplParameterResultDifferentiability)
136+
NODE(ImplParameterTransferring)
136137
NODE(ImplFunctionAttribute)
137138
NODE(ImplFunctionConvention)
138139
NODE(ImplFunctionConventionName)
@@ -149,7 +150,9 @@ NODE(InfixOperator)
149150
CONTEXT_NODE(Initializer)
150151
CONTEXT_NODE(InitAccessor)
151152
NODE(Isolated)
153+
NODE(Transferring)
152154
NODE(IsolatedAnyFunctionType)
155+
NODE(TransferringResultFunctionType)
153156
NODE(KeyPathGetterThunkHelper)
154157
NODE(KeyPathSetterThunkHelper)
155158
NODE(KeyPathEqualsThunkHelper)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ class Demangler : public NodeFactory {
566566
NodePointer demangleInitializer();
567567
NodePointer demangleImplParamConvention(Node::Kind ConvKind);
568568
NodePointer demangleImplResultConvention(Node::Kind ConvKind);
569+
NodePointer demangleImplParameterTransferring();
569570
NodePointer demangleImplParameterResultDifferentiability();
570571
NodePointer demangleImplFunctionType();
571572
NodePointer demangleClangType();

include/swift/Demangling/TypeDecoder.h

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class FunctionParam {
7878
}
7979
void setNoDerivative() { Flags = Flags.withNoDerivative(true); }
8080
void setIsolated() { Flags = Flags.withIsolated(true); }
81+
void setTransferring() { Flags = Flags.withTransferring(true); }
8182
void setFlags(ParameterFlags flags) { Flags = flags; };
8283

8384
FunctionParam withLabel(StringRef label) const {
@@ -109,6 +110,7 @@ enum class ImplParameterConvention {
109110

110111
enum class ImplParameterInfoFlags : uint8_t {
111112
NotDifferentiable = 0x1,
113+
Transferring = 0x2,
112114
};
113115

114116
using ImplParameterInfoOptions = OptionSet<ImplParameterInfoFlags>;
@@ -282,72 +284,88 @@ class ImplFunctionTypeFlags {
282284
unsigned Async : 1;
283285
unsigned ErasedIsolation : 1;
284286
unsigned DifferentiabilityKind : 3;
287+
unsigned HasTransferringResult : 1;
285288

286289
public:
287290
ImplFunctionTypeFlags()
288291
: Rep(0), Pseudogeneric(0), Escaping(0), Concurrent(0), Async(0),
289-
ErasedIsolation(0), DifferentiabilityKind(0) {}
292+
ErasedIsolation(0), DifferentiabilityKind(0), HasTransferringResult(0) {
293+
}
290294

291295
ImplFunctionTypeFlags(ImplFunctionRepresentation rep, bool pseudogeneric,
292296
bool noescape, bool concurrent, bool async,
293297
bool erasedIsolation,
294-
ImplFunctionDifferentiabilityKind diffKind)
298+
ImplFunctionDifferentiabilityKind diffKind,
299+
bool hasTransferringResult)
295300
: Rep(unsigned(rep)), Pseudogeneric(pseudogeneric), Escaping(noescape),
296301
Concurrent(concurrent), Async(async), ErasedIsolation(erasedIsolation),
297-
DifferentiabilityKind(unsigned(diffKind)) {}
302+
DifferentiabilityKind(unsigned(diffKind)),
303+
HasTransferringResult(hasTransferringResult) {}
298304

299305
ImplFunctionTypeFlags
300306
withRepresentation(ImplFunctionRepresentation rep) const {
301307
return ImplFunctionTypeFlags(
302308
rep, Pseudogeneric, Escaping, Concurrent, Async, ErasedIsolation,
303-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
309+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
310+
HasTransferringResult);
304311
}
305312

306313
ImplFunctionTypeFlags
307314
withConcurrent() const {
308315
return ImplFunctionTypeFlags(
309-
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, true,
310-
Async, ErasedIsolation,
311-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
316+
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, true, Async,
317+
ErasedIsolation,
318+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
319+
HasTransferringResult);
312320
}
313321

314322
ImplFunctionTypeFlags
315323
withAsync() const {
316324
return ImplFunctionTypeFlags(
317325
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, Concurrent,
318326
true, ErasedIsolation,
319-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
327+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
328+
HasTransferringResult);
320329
}
321330

322331
ImplFunctionTypeFlags
323332
withEscaping() const {
324333
return ImplFunctionTypeFlags(
325334
ImplFunctionRepresentation(Rep), Pseudogeneric, true, Concurrent, Async,
326335
ErasedIsolation,
327-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
336+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
337+
HasTransferringResult);
328338
}
329339

330340
ImplFunctionTypeFlags
331341
withErasedIsolation() const {
332342
return ImplFunctionTypeFlags(
333343
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, Concurrent,
334-
Async, true,
335-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
344+
Async, true, ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
345+
HasTransferringResult);
336346
}
337347

338348
ImplFunctionTypeFlags
339349
withPseudogeneric() const {
340350
return ImplFunctionTypeFlags(
341351
ImplFunctionRepresentation(Rep), true, Escaping, Concurrent, Async,
342352
ErasedIsolation,
343-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
353+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind),
354+
HasTransferringResult);
344355
}
345356

346357
ImplFunctionTypeFlags
347358
withDifferentiabilityKind(ImplFunctionDifferentiabilityKind diffKind) const {
348359
return ImplFunctionTypeFlags(ImplFunctionRepresentation(Rep), Pseudogeneric,
349360
Escaping, Concurrent, Async, ErasedIsolation,
350-
diffKind);
361+
diffKind, HasTransferringResult);
362+
}
363+
364+
ImplFunctionTypeFlags withTransferringResult() const {
365+
return ImplFunctionTypeFlags(
366+
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, Concurrent,
367+
Async, ErasedIsolation,
368+
ImplFunctionDifferentiabilityKind(DifferentiabilityKind), true);
351369
}
352370

353371
ImplFunctionRepresentation getRepresentation() const {
@@ -364,6 +382,8 @@ class ImplFunctionTypeFlags {
364382

365383
bool hasErasedIsolation() const { return ErasedIsolation; }
366384

385+
bool hasTransferringResult() const { return HasTransferringResult; }
386+
367387
bool isDifferentiable() const {
368388
return getDifferentiabilityKind() !=
369389
ImplFunctionDifferentiabilityKind::NonDifferentiable;
@@ -866,6 +886,10 @@ class TypeDecoder {
866886
} else if (Node->getChild(firstChildIdx)->getKind() ==
867887
NodeKind::IsolatedAnyFunctionType) {
868888
extFlags = extFlags.withIsolatedAny();
889+
} else if (Node->getChild(firstChildIdx)->getKind() ==
890+
NodeKind::TransferringResultFunctionType) {
891+
extFlags = extFlags.withTransferringResult();
892+
++firstChildIdx;
869893
}
870894

871895
FunctionMetadataDifferentiabilityKind diffKind;
@@ -1706,6 +1730,12 @@ class TypeDecoder {
17061730
hasParamFlags = true;
17071731
break;
17081732

1733+
case NodeKind::Transferring:
1734+
param.setTransferring();
1735+
node = node->getFirstChild();
1736+
hasParamFlags = true;
1737+
break;
1738+
17091739
case NodeKind::AutoClosureType:
17101740
case NodeKind::EscapingAutoClosureType:
17111741
param.setAutoClosure();

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,8 @@ class TypeRefBuilder {
11631163
funcFlags = funcFlags.withConcurrent(flags.isSendable());
11641164
funcFlags = funcFlags.withAsync(flags.isAsync());
11651165
funcFlags = funcFlags.withDifferentiable(flags.isDifferentiable());
1166+
extFuncFlags =
1167+
extFuncFlags.withTransferringResult(flags.hasTransferringResult());
11661168

11671169
FunctionMetadataDifferentiabilityKind diffKind;
11681170
switch (flags.getDifferentiabilityKind()) {

lib/AST/ASTDemangler.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ Type ASTBuilder::createFunctionType(
414414
.withVariadic(flags.isVariadic())
415415
.withAutoClosure(flags.isAutoClosure())
416416
.withNoDerivative(flags.isNoDerivative())
417-
.withIsolated(flags.isIsolated());
417+
.withIsolated(flags.isIsolated())
418+
.withTransferring(flags.isTransferring());
418419

419420
hasIsolatedParameter |= flags.isIsolated();
420421
funcParams.push_back(AnyFunctionType::Param(type, label, parameterFlags));
@@ -472,7 +473,7 @@ Type ASTBuilder::createFunctionType(
472473
auto einfo = FunctionType::ExtInfoBuilder(
473474
representation, noescape, flags.isThrowing(), thrownError,
474475
resultDiffKind, clangFunctionType, isolation,
475-
LifetimeDependenceInfo(), false /*is transferring*/)
476+
LifetimeDependenceInfo(), extFlags.hasTransferringResult())
476477
.withAsync(flags.isAsync())
477478
.withConcurrent(flags.isSendable())
478479
.build();
@@ -517,6 +518,11 @@ getParameterOptions(ImplParameterInfoOptions implOptions) {
517518
result |= SILParameterInfo::NotDifferentiable;
518519
}
519520

521+
if (implOptions.contains(ImplParameterInfoFlags::Transferring)) {
522+
implOptions -= ImplParameterInfoFlags::Transferring;
523+
result |= SILParameterInfo::Transferring;
524+
}
525+
520526
// If we did not handle all flags in implOptions, this code was not updated
521527
// appropriately. Return None to signal error.
522528
if (bool(implOptions))
@@ -659,7 +665,7 @@ Type ASTBuilder::createImplFunctionType(
659665
representation, flags.isPseudogeneric(), !flags.isEscaping(),
660666
flags.isSendable(), flags.isAsync(), unimplementable,
661667
isolation, diffKind, clangFnType, LifetimeDependenceInfo(),
662-
false /*has transferring result*/)
668+
flags.hasTransferringResult())
663669
.build();
664670

665671
return SILFunctionType::get(genericSig, einfo, funcCoroutineKind,

lib/AST/ASTMangler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,9 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
19891989
if (!fn->isNoEscape())
19901990
OpArgs.push_back('e');
19911991

1992+
if (fn->hasTransferringResult())
1993+
OpArgs.push_back('T');
1994+
19921995
switch (fn->getIsolation()) {
19931996
case SILFunctionTypeIsolation::Unknown:
19941997
break;
@@ -2089,6 +2092,8 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
20892092
// Mangle the parameters.
20902093
for (auto param : fn->getParameters()) {
20912094
OpArgs.push_back(getParamConvention(param.getConvention()));
2095+
if (param.hasOption(SILParameterInfo::Transferring))
2096+
OpArgs.push_back('T');
20922097
if (auto diffKind = getParamDifferentiability(param.getOptions()))
20932098
OpArgs.push_back(*diffKind);
20942099
appendType(param.getInterfaceType(), sig, forDecl);
@@ -2858,6 +2863,10 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
28582863
break;
28592864
}
28602865

2866+
if (fn->hasTransferringResult()) {
2867+
appendOperator("YT");
2868+
}
2869+
28612870
if (auto *afd = dyn_cast_or_null<AbstractFunctionDecl>(forDecl)) {
28622871
if (afd->hasImplicitSelfDecl()) {
28632872
auto lifetimeDependenceKind =
@@ -3034,7 +3043,8 @@ void ASTMangler::appendParameterTypeListElement(
30343043
}
30353044
if (flags.isIsolated())
30363045
appendOperator("Yi");
3037-
3046+
if (flags.isTransferring())
3047+
appendOperator("Yu");
30383048
if (flags.isCompileTimeConst())
30393049
appendOperator("Yt");
30403050

lib/Demangling/Demangler.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,11 @@ NodePointer Demangler::demangleTypeAnnotation() {
951951
case 't':
952952
return createType(
953953
createWithChild(Node::Kind::CompileTimeConst, popTypeAndGetChild()));
954+
case 'T':
955+
return createNode(Node::Kind::TransferringResultFunctionType);
956+
case 'u':
957+
return createType(
958+
createWithChild(Node::Kind::Transferring, popTypeAndGetChild()));
954959
case 'l':
955960
return demangleLifetimeDependenceKind(/*isSelfDependence*/ false);
956961
case 'L':
@@ -1556,6 +1561,7 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
15561561
addChild(FuncType, ClangType);
15571562
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
15581563
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
1564+
addChild(FuncType, popNode(Node::Kind::TransferringResultFunctionType));
15591565
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
15601566
addChild(FuncType, popNode([](Node::Kind kind) {
15611567
return kind == Node::Kind::ThrowsAnnotation ||
@@ -1602,6 +1608,9 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16021608
if (FuncType->getChild(FirstChildIdx)->getKind()
16031609
== Node::Kind::IsolatedAnyFunctionType)
16041610
++FirstChildIdx;
1611+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1612+
Node::Kind::TransferringResultFunctionType)
1613+
++FirstChildIdx;
16051614
if (FuncType->getChild(FirstChildIdx)->getKind()
16061615
== Node::Kind::DifferentiableFunctionType)
16071616
++FirstChildIdx;
@@ -2155,6 +2164,14 @@ NodePointer Demangler::demangleImplResultConvention(Node::Kind ConvKind) {
21552164
createNode(Node::Kind::ImplConvention, attr));
21562165
}
21572166

2167+
NodePointer Demangler::demangleImplParameterTransferring() {
2168+
// Empty string represents default differentiability.
2169+
if (!nextIf('T'))
2170+
return nullptr;
2171+
const char *attr = "transferring";
2172+
return createNode(Node::Kind::ImplParameterTransferring, attr);
2173+
}
2174+
21582175
NodePointer Demangler::demangleImplParameterResultDifferentiability() {
21592176
// Empty string represents default differentiability.
21602177
const char *attr = "";
@@ -2298,6 +2315,8 @@ NodePointer Demangler::demangleImplFunctionType() {
22982315
type = addChild(type, Param);
22992316
if (NodePointer Diff = demangleImplParameterResultDifferentiability())
23002317
Param = addChild(Param, Diff);
2318+
if (auto Transferring = demangleImplParameterTransferring())
2319+
Param = addChild(Param, Transferring);
23012320
++NumTypesToAdd;
23022321
}
23032322
while (NodePointer Result = demangleImplResultConvention(

0 commit comments

Comments
 (0)