Skip to content

Commit fa932e7

Browse files
committed
Fix the demangling of sending result types when combined with isolation
Fixes the immediate problem, but the presence of demangling code in the runtime means that we'll need a follow-up to fix the compiler so that it doesn't try to use the demangler to materialize metadata for function types that have both isolation and a sending result. rdar://142443925
1 parent cf4d825 commit fa932e7

File tree

7 files changed

+82
-28
lines changed

7 files changed

+82
-28
lines changed

docs/ABI/Mangling.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,12 @@ Types
733733
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
734734
FUNCTION-KIND ::= 'E' // function type (noescape)
735735

736-
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
737-
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
736+
C-TYPE ::= NATURAL CHAR* // raw Itanium mangling
738737

739-
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
738+
function-signature ::= result-type params-type async? sendable? throws? differentiable? function-isolation? sending-result? // results and parameters
739+
740+
result-type ::= type
741+
result-type ::= empty-list // shortcut for ()
740742

741743
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
742744
// with optional inout convention, shared convention. parameters don't have labels,
@@ -752,6 +754,7 @@ Types
752754
#if SWIFT_RUNTIME_VERSION >= 6.0
753755
throws ::= type 'YK' // 'throws(type)' annotation on function types
754756
function-isolation ::= type 'YA' // @isolated(any) on function type
757+
sending-result ::= 'YT' // -> sending T
755758
#endif
756759
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
757760
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
@@ -763,6 +766,12 @@ Types
763766
// FIXME: Consider replacing 'h' with a two-char code
764767
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'Yi'? 'd'? 'Yt'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, actor 'isolated', variadic specifier, and compile-time constant
765768

769+
In the mangling of C function types,``C-TYPE`` is mangled according to the Itanium ABI, prefixed with its length. This resembles the mangling of ``identifier``, but it does not honor substitutions or Punycode.
770+
771+
The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when it's combined with ``function-isolation``.
772+
773+
::
774+
766775
METATYPE-REPR ::= 't' // Thin metatype representation
767776
METATYPE-REPR ::= 'T' // Thick metatype representation
768777
METATYPE-REPR ::= 'o' // ObjC metatype representation

include/swift/Demangling/TypeDecoder.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,12 @@ class TypeDecoder {
915915
++firstChildIdx;
916916
}
917917

918+
if (Node->getChild(firstChildIdx)->getKind() ==
919+
NodeKind::SendingResultFunctionType) {
920+
extFlags = extFlags.withSendingResult();
921+
++firstChildIdx;
922+
}
923+
918924
BuiltType globalActorType = BuiltType();
919925
if (Node->getChild(firstChildIdx)->getKind() ==
920926
NodeKind::GlobalActorFunctionType) {
@@ -937,12 +943,6 @@ class TypeDecoder {
937943
++firstChildIdx;
938944
}
939945

940-
if (Node->getChild(firstChildIdx)->getKind() ==
941-
NodeKind::SendingResultFunctionType) {
942-
extFlags = extFlags.withSendingResult();
943-
++firstChildIdx;
944-
}
945-
946946
FunctionMetadataDifferentiabilityKind diffKind;
947947
if (Node->getChild(firstChildIdx)->getKind() ==
948948
NodeKind::DifferentiableFunctionType) {

lib/Demangling/Demangler.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,24 +1634,51 @@ NodePointer Demangler::demanglePlainFunction() {
16341634

16351635
NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
16361636
NodePointer FuncType = createNode(kind);
1637+
1638+
// Demangle a C function type if the function node kind says that
1639+
// one follows.
16371640
NodePointer ClangType = nullptr;
16381641
if (hasClangType) {
16391642
ClangType = demangleClangType();
16401643
}
16411644
addChild(FuncType, ClangType);
1642-
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
1643-
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
1645+
1646+
// The components of function-signature. Note that these need to be
1647+
// popped in the reverse of the order they're mangled. If you add a
1648+
// new component, be sure to add a demangling test case for combinations
1649+
// of specifiers.
1650+
1651+
// sending-result?
16441652
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
1653+
1654+
// function-isolation?
1655+
auto isFunctionIsolation = [](Node::Kind kind) {
1656+
return kind == Node::Kind::GlobalActorFunctionType ||
1657+
kind == Node::Kind::IsolatedAnyFunctionType;
1658+
};
1659+
addChild(FuncType, popNode(isFunctionIsolation));
1660+
1661+
// differentiable?
16451662
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
1663+
1664+
// throws?
16461665
addChild(FuncType, popNode([](Node::Kind kind) {
16471666
return kind == Node::Kind::ThrowsAnnotation ||
16481667
kind == Node::Kind::TypedThrowsAnnotation;
16491668
}));
1669+
1670+
// sendable?
16501671
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
1672+
1673+
// async?
16511674
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
16521675

1676+
// params-type
16531677
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
1678+
1679+
// result-type
16541680
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
1681+
16551682
return createType(FuncType);
16561683
}
16571684

@@ -1681,15 +1708,15 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16811708
return nullptr;
16821709

16831710
unsigned FirstChildIdx = 0;
1711+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1712+
Node::Kind::SendingResultFunctionType)
1713+
++FirstChildIdx;
16841714
if (FuncType->getChild(FirstChildIdx)->getKind()
16851715
== Node::Kind::GlobalActorFunctionType)
16861716
++FirstChildIdx;
16871717
if (FuncType->getChild(FirstChildIdx)->getKind()
16881718
== Node::Kind::IsolatedAnyFunctionType)
16891719
++FirstChildIdx;
1690-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1691-
Node::Kind::SendingResultFunctionType)
1692-
++FirstChildIdx;
16931720
if (FuncType->getChild(FirstChildIdx)->getKind()
16941721
== Node::Kind::DifferentiableFunctionType)
16951722
++FirstChildIdx;

lib/Demangling/NodePrinter.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,18 @@ class NodePrinter {
898898
// handled earlier
899899
++startIndex;
900900
}
901+
902+
// Be sure to check for function signature components in the same
903+
// order that they're added by the demangler, which is the reverse
904+
// of the order that they appear in the mangling grammar.
905+
906+
if (node->getChild(startIndex)->getKind() ==
907+
Node::Kind::SendingResultFunctionType) {
908+
++startIndex;
909+
hasSendingResult = true;
910+
}
911+
912+
// function-isolation; note that these can't actually both appear.
901913
if (node->getChild(startIndex)->getKind()
902914
== Node::Kind::IsolatedAnyFunctionType) {
903915
print(node->getChild(startIndex), depth + 1);
@@ -908,6 +920,7 @@ class NodePrinter {
908920
print(node->getChild(startIndex), depth + 1);
909921
++startIndex;
910922
}
923+
911924
if (node->getChild(startIndex)->getKind() ==
912925
Node::Kind::DifferentiableFunctionType) {
913926
diffKind =
@@ -932,11 +945,6 @@ class NodePrinter {
932945
++startIndex;
933946
isAsync = true;
934947
}
935-
if (node->getChild(startIndex)->getKind() ==
936-
Node::Kind::SendingResultFunctionType) {
937-
++startIndex;
938-
hasSendingResult = true;
939-
}
940948

941949
switch (diffKind) {
942950
case MangledDifferentiabilityKind::Forward:

stdlib/public/RemoteInspection/TypeRef.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,15 @@ class DemanglingForTypeRef
766766

767767
auto funcNode = Dem.createNode(kind);
768768

769+
// This needs to use the same order as the demangler.
770+
771+
// TODO: the C function type would go here
772+
773+
if (F->getExtFlags().hasSendingResult()) {
774+
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
775+
funcNode->addChild(node, Dem);
776+
}
777+
769778
if (auto globalActor = F->getGlobalActor()) {
770779
auto node = Dem.createNode(Node::Kind::GlobalActorFunctionType);
771780
auto globalActorNode = visit(globalActor);
@@ -774,9 +783,6 @@ class DemanglingForTypeRef
774783
} else if (F->getExtFlags().isIsolatedAny()) {
775784
auto node = Dem.createNode(Node::Kind::IsolatedAnyFunctionType);
776785
funcNode->addChild(node, Dem);
777-
} else if (F->getExtFlags().hasSendingResult()) {
778-
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
779-
funcNode->addChild(node, Dem);
780786
}
781787

782788
if (F->getFlags().isDifferentiable()) {

stdlib/public/runtime/Demangle.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,14 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
741741

742742
NodePointer result = Dem.createNode(Node::Kind::ReturnType);
743743
result->addChild(resultTy, Dem);
744-
744+
745745
auto funcNode = Dem.createNode(kind);
746+
// Add the components of the function-signature production in the same
747+
// order that the demangler would.
748+
// TODO: C function type would go here
749+
if (func->getExtendedFlags().hasSendingResult())
750+
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
751+
Dem);
746752
if (func->hasGlobalActor()) {
747753
auto globalActorTypeNode =
748754
_swift_buildDemanglingForMetadata(func->getGlobalActor(), Dem);
@@ -798,10 +804,6 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
798804
if (func->isAsync())
799805
funcNode->addChild(Dem.createNode(Node::Kind::AsyncAnnotation), Dem);
800806

801-
if (func->getExtendedFlags().hasSendingResult())
802-
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
803-
Dem);
804-
805807
funcNode->addChild(parameters, Dem);
806808
funcNode->addChild(result, Dem);
807809
return funcNode;

test/Demangle/Inputs/manglings.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ $sS3fIedgyywTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swi
465465
$sS3fIedgyyTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swift.Float, @unowned sending Swift.Float) -> (@unowned Swift.Float)
466466
$s4testA2A5KlassCyYTF ---> test.test() -> sending test.Klass
467467
$s4main5KlassCACYTcMD ---> demangling cache variable for type metadata for (main.Klass) -> sending main.Klass
468-
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() -> sending null.NonSendableKlass
468+
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() async -> sending null.NonSendableKlass
469469
$s4null16NonSendableKlassCIegHo_ACs5Error_pIegHTrzo_TR ---> {T:} reabstraction thunk helper from @escaping @callee_guaranteed @async () -> (@owned null.NonSendableKlass) to @escaping @callee_guaranteed @async () -> sending (@out null.NonSendableKlass, @error @owned Swift.Error)
470470
$sSRyxG15Synchronization19AtomicRepresentableABRi_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Copyable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
471471
$sSRyxG15Synchronization19AtomicRepresentableABRi0_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Escapable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
@@ -483,3 +483,5 @@ $s4mainAAyyycAA1CCFTTH ---> hop to main actor thunk of main.main(main.C) -> () -
483483

484484
$s4main6VectorVy$1_SiG ---> main.Vector<2, Swift.Int>
485485
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>
486+
$s3red7MyActorC3runyxxyYaKACYcYTXEYaKlFZ ---> static red.MyActor.run<A>(@red.MyActor () async throws -> sending A) async throws -> A
487+
$s3red7MyActorC3runyxxyYaKYAYTXEYaKlFZ ---> static red.MyActor.run<A>(@isolated(any) () async throws -> sending A) async throws -> A

0 commit comments

Comments
 (0)